From: xxh Date: Wed, 25 Mar 2015 04:19:16 +0000 (+0800) Subject: update 8723bu wifi driver X-Git-Tag: firefly_0821_release~4233 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=428053ce3e2226ad3b259d2282ba6da250501885;p=firefly-linux-kernel-4.4.55.git update 8723bu wifi driver 1.Improve_P2P_compatibility for Android L 2.Fix_HiddenAP_handle 3.P2P ScanSparse For Miracas --- diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/Kconfig b/drivers/net/wireless/rockchip_wlan/rtl8723bu/Kconfig index a84ff814ee69..4d065ff94f1a 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/Kconfig +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/Kconfig @@ -1,5 +1,10 @@ config RTL8723BU tristate "Realtek 8723BU USB WiFi" depends on USB + select WIRELESS_EXT + select WEXT_PRIV + select IEEE80211 + select BT_RTKBTUSB + select UHID ---help--- Help message of RTL8723BU diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/Makefile b/drivers/net/wireless/rockchip_wlan/rtl8723bu/Makefile index 8f38c324b57f..fd344535a3b5 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/Makefile +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/Makefile @@ -1,5 +1,5 @@ EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) -EXTRA_CFLAGS += -O1 -Wframe-larger-than=1200 +EXTRA_CFLAGS += -O1 #EXTRA_CFLAGS += -O3 #EXTRA_CFLAGS += -Wall #EXTRA_CFLAGS += -Wextra @@ -53,20 +53,26 @@ CONFIG_TRAFFIC_PROTECT = y CONFIG_LOAD_PHY_PARA_FROM_FILE = y CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY = n CONFIG_CALIBRATE_TX_POWER_TO_MAX = n -CONFIG_RTW_ADAPTIVITY_EN = auto +CONFIG_RTW_ADAPTIVITY_EN = disable CONFIG_RTW_ADAPTIVITY_MODE = normal CONFIG_SKIP_SIGNAL_SCALE_MAPPING = n +CONFIG_80211W = n +CONFIG_REDUCE_TX_CPU_LOADING = n +CONFIG_BR_EXT = y +CONFIG_ANTENNA_DIVERSITY = n ######################## Wake On Lan ########################## CONFIG_WOWLAN = n CONFIG_GPIO_WAKEUP = n +CONFIG_WAKEUP_GPIO_IDX = default CONFIG_PNO_SUPPORT = n CONFIG_PNO_SET_DEBUG = n CONFIG_AP_WOWLAN = n ######### Notify SDIO Host Keep Power During Syspend ########## CONFIG_RTW_SDIO_PM_KEEP_POWER = y ###################### Platform Related ####################### -CONFIG_PLATFORM_I386_PC = n +CONFIG_PLATFORM_I386_PC = y CONFIG_PLATFORM_ANDROID_X86 = n +CONFIG_PLATFORM_ANDROID_INTEL_X86 = n CONFIG_PLATFORM_JB_X86 = n CONFIG_PLATFORM_ARM_S3C2K4 = n CONFIG_PLATFORM_ARM_PXA2XX = n @@ -108,6 +114,7 @@ CONFIG_PLATFORM_ARM_SPREADTRUM_8810 = n CONFIG_PLATFORM_ARM_WMT = n CONFIG_PLATFORM_TI_DM365 = n CONFIG_PLATFORM_MOZART = n +CONFIG_PLATFORM_RTK119X = n ############################################################### CONFIG_DRVEXT_MODULE = n @@ -141,6 +148,7 @@ _OS_INTFS_FILES := os_dep/osdep_service.o \ os_dep/linux/mlme_linux.o \ os_dep/linux/recv_linux.o \ os_dep/linux/ioctl_cfg80211.o \ + os_dep/linux/rtw_cfgvendor.o \ os_dep/linux/wifi_regd.o \ os_dep/linux/rtw_android.o \ os_dep/linux/rtw_proc.o @@ -160,25 +168,29 @@ _HAL_INTFS_FILES := hal/hal_intf.o \ hal/hal_com.o \ hal/hal_com_phycfg.o \ hal/hal_phy.o \ + hal/hal_dm.o \ hal/hal_btcoex.o \ hal/hal_hci/hal_$(HCI_NAME).o \ hal/led/hal_$(HCI_NAME)_led.o - -_OUTSRC_FILES := hal/OUTSRC/odm_debug.o \ - hal/OUTSRC/odm_AntDiv.o\ - hal/OUTSRC/odm_interface.o\ - hal/OUTSRC/odm_HWConfig.o\ - hal/OUTSRC/odm.o\ + +_OUTSRC_FILES := hal/OUTSRC/phydm_debug.o \ + hal/OUTSRC/phydm_AntDiv.o\ + hal/OUTSRC/phydm_interface.o\ + hal/OUTSRC/phydm_HWConfig.o\ + hal/OUTSRC/phydm.o\ hal/OUTSRC/HalPhyRf.o\ - hal/OUTSRC/odm_EdcaTurboCheck.o\ - hal/OUTSRC/odm_DIG.o\ - hal/OUTSRC/odm_PathDiv.o\ - hal/OUTSRC/odm_RaInfo.o\ - hal/OUTSRC/odm_DynamicBBPowerSaving.o\ - hal/OUTSRC/odm_DynamicTxPower.o\ - hal/OUTSRC/odm_CfoTracking.o\ - hal/OUTSRC/odm_NoiseMonitor.o - + hal/OUTSRC/phydm_EdcaTurboCheck.o\ + hal/OUTSRC/phydm_DIG.o\ + hal/OUTSRC/phydm_PathDiv.o\ + hal/OUTSRC/phydm_RaInfo.o\ + hal/OUTSRC/phydm_DynamicBBPowerSaving.o\ + hal/OUTSRC/phydm_PowerTracking.o\ + hal/OUTSRC/phydm_DynamicTxPower.o\ + hal/OUTSRC/PhyDM_Adaptivity.o\ + hal/OUTSRC/phydm_CfoTracking.o\ + hal/OUTSRC/phydm_NoiseMonitor.o\ + hal/OUTSRC/phydm_ACS.o + EXTRA_CFLAGS += -I$(src)/platform _PLATFORM_FILES := platform/platform_ops.o @@ -198,8 +210,8 @@ _OUTSRC_FILES += hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.o \ hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.o \ hal/OUTSRC-BTCoexist/HalBtc8821aCsr2Ant.o endif - -########### HAL_RTL8192C ################################# + +########### HAL_RTL8192C ################################# ifeq ($(CONFIG_RTL8192C), y) RTL871X = rtl8192c @@ -224,7 +236,7 @@ _HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_hal_init.o \ hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_halinit.o \ hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_led.o \ hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_xmit.o \ - hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_recv.o + hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_recv.o _HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o @@ -233,7 +245,7 @@ ifeq ($(CONFIG_MP_INCLUDED), y) _HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_mp.o endif -_OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/odm_RTL8192C.o\ +_OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/phydm_RTL8192C.o\ hal/OUTSRC/$(RTL871X)/HalDMOutSrc8192C_CE.o ifeq ($(CONFIG_USB_HCI), y) @@ -281,10 +293,10 @@ ifeq ($(CONFIG_MP_INCLUDED), y) _HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_mp.o endif -_OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/odm_RTL8192D.o\ +_OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/phydm_RTL8192D.o\ hal/OUTSRC/$(RTL871X)/HalDMOutSrc8192D_CE.o - + ifeq ($(CONFIG_USB_HCI), y) _OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/Hal8192DUFWImg_CE.o \ hal/OUTSRC/$(RTL871X)/Hal8192DUPHYImg_CE.o \ @@ -321,7 +333,7 @@ _HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ hal/$(RTL871X)/Hal8723PwrSeq.o\ hal/$(RTL871X)/$(RTL871X)_xmit.o \ hal/$(RTL871X)/$(RTL871X)_sreset.o - + _HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_hal_init.o \ hal/$(RTL871X)/$(RTL871X)_phycfg.o \ hal/$(RTL871X)/$(RTL871X)_rf6052.o \ @@ -332,7 +344,7 @@ _HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_hal_init.o \ hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_led.o \ hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_xmit.o \ hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_recv.o - + ifeq ($(CONFIG_SDIO_HCI), y) _HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o else @@ -367,7 +379,7 @@ endif _OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/HalHWImg8723A_BB.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8723A_MAC.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8723A_RF.o\ - hal/OUTSRC/$(RTL871X)/odm_RegConfig8723A.o + hal/OUTSRC/$(RTL871X)/phydm_RegConfig8723A.o _OUTSRC_FILES += hal/OUTSRC/rtl8192c/HalDMOutSrc8192C_CE.o @@ -424,7 +436,7 @@ endif ifeq ($(CONFIG_MP_INCLUDED), y) _HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_mp.o -endif +endif #hal/OUTSRC/$(RTL871X)/Hal8188EFWImg_CE.o _OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/HalHWImg8188E_MAC.o\ @@ -432,9 +444,9 @@ _OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/HalHWImg8188E_MAC.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8188E_RF.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8188E_FW.o\ hal/OUTSRC/$(RTL871X)/HalPhyRf_8188e.o\ - hal/OUTSRC/$(RTL871X)/odm_RegConfig8188E.o\ + hal/OUTSRC/$(RTL871X)/phydm_RegConfig8188E.o\ hal/OUTSRC/$(RTL871X)/Hal8188ERateAdaptive.o\ - hal/OUTSRC/$(RTL871X)/odm_RTL8188E.o + hal/OUTSRC/$(RTL871X)/phydm_RTL8188E.o endif @@ -490,8 +502,8 @@ _OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/HalHWImg8192E_MAC.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8192E_RF.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8192E_FW.o\ hal/OUTSRC/$(RTL871X)/HalPhyRf_8192e.o\ - hal/OUTSRC/$(RTL871X)/odm_RegConfig8192E.o\ - hal/OUTSRC/$(RTL871X)/odm_RTL8192E.o + hal/OUTSRC/$(RTL871X)/phydm_RegConfig8192E.o\ + hal/OUTSRC/$(RTL871X)/phydm_RTL8192E.o endif @@ -548,8 +560,8 @@ _OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/HalHWImg8812A_FW.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8812A_BB.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8812A_RF.o\ hal/OUTSRC/$(RTL871X)/HalPhyRf_8812A.o\ - hal/OUTSRC/$(RTL871X)/odm_RegConfig8812A.o\ - hal/OUTSRC/$(RTL871X)/odm_RTL8812A.o + hal/OUTSRC/$(RTL871X)/phydm_RegConfig8812A.o\ + hal/OUTSRC/$(RTL871X)/phydm_RTL8812A.o endif ifeq ($(CONFIG_RTL8821A), y) @@ -576,9 +588,10 @@ _OUTSRC_FILES += hal/OUTSRC/rtl8821a/HalHWImg8821A_FW.o\ hal/OUTSRC/rtl8821a/HalHWImg8821A_RF.o\ hal/OUTSRC/rtl8812a/HalPhyRf_8812A.o\ hal/OUTSRC/rtl8821a/HalPhyRf_8821A.o\ - hal/OUTSRC/rtl8821a/odm_RegConfig8821A.o\ - hal/OUTSRC/rtl8821a/odm_RTL8821A.o -endif + hal/OUTSRC/rtl8821a/phydm_RegConfig8821A.o\ + hal/OUTSRC/rtl8821a/phydm_RTL8821A.o\ + hal/OUTSRC/rtl8821a/PhyDM_IQK_8821A.o +endif endif @@ -609,7 +622,7 @@ _HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_hal_init.o \ hal/$(RTL871X)/$(RTL871X)_dm.o \ hal/$(RTL871X)/$(RTL871X)_rxdesc.o \ hal/$(RTL871X)/$(RTL871X)_cmd.o \ - + _HAL_INTFS_FILES += \ hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_halinit.o \ @@ -632,20 +645,20 @@ _OUTSRC_FILES += hal/OUTSRC/$(RTL871X)/HalHWImg8723B_BB.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8723B_RF.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8723B_FW.o\ hal/OUTSRC/$(RTL871X)/HalHWImg8723B_MP.o\ - hal/OUTSRC/$(RTL871X)/odm_RegConfig8723B.o\ + hal/OUTSRC/$(RTL871X)/phydm_RegConfig8723B.o\ hal/OUTSRC/$(RTL871X)/HalPhyRf_8723B.o\ - hal/OUTSRC/$(RTL871X)/odm_RTL8723B.o + hal/OUTSRC/$(RTL871X)/phydm_RTL8723B.o endif -########### AUTO_CFG ################################# - +########### AUTO_CFG ################################# + ifeq ($(CONFIG_AUTOCFG_CP), y) -ifeq ($(CONFIG_MULTIDRV), y) +ifeq ($(CONFIG_MULTIDRV), y) $(shell cp $(TopDIR)/autoconf_multidrv_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) else -ifeq ($(CONFIG_RTL8188E)$(CONFIG_SDIO_HCI),yy) +ifeq ($(CONFIG_RTL8188E)$(CONFIG_SDIO_HCI),yy) $(shell cp $(TopDIR)/autoconf_rtl8189e_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) else $(shell cp $(TopDIR)/autoconf_$(RTL871X)_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) @@ -701,6 +714,8 @@ ifeq ($(CONFIG_EFUSE_CONFIG_FILE), y) EXTRA_CFLAGS += -DCONFIG_EFUSE_CONFIG_FILE ifeq ($(MODULE_NAME), 8189es) EXTRA_CFLAGS += -DEFUSE_MAP_PATH=\"/system/etc/wifi/wifi_efuse_8189e.map\" +else ifeq ($(MODULE_NAME), 8723bs) +EXTRA_CFLAGS += -DEFUSE_MAP_PATH=\"/system/etc/wifi/wifi_efuse_8723bs.map\" else EXTRA_CFLAGS += -DEFUSE_MAP_PATH=\"/system/etc/wifi/wifi_efuse_$(MODULE_NAME).map\" endif @@ -717,6 +732,8 @@ endif ifeq ($(CONFIG_LOAD_PHY_PARA_FROM_FILE), y) EXTRA_CFLAGS += -DCONFIG_LOAD_PHY_PARA_FROM_FILE +#EXTRA_CFLAGS += -DREALTEK_CONFIG_PATH=\"/lib/firmware/\" +EXTRA_CFLAGS += -DREALTEK_CONFIG_PATH=\"\" endif ifeq ($(CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY), y) @@ -731,8 +748,6 @@ ifeq ($(CONFIG_RTW_ADAPTIVITY_EN), disable) EXTRA_CFLAGS += -DCONFIG_RTW_ADAPTIVITY_EN=0 else ifeq ($(CONFIG_RTW_ADAPTIVITY_EN), enable) EXTRA_CFLAGS += -DCONFIG_RTW_ADAPTIVITY_EN=1 -else ifeq ($(CONFIG_RTW_ADAPTIVITY_EN), auto) -EXTRA_CFLAGS += -DCONFIG_RTW_ADAPTIVITY_EN=2 endif ifeq ($(CONFIG_RTW_ADAPTIVITY_MODE), normal) @@ -745,6 +760,10 @@ ifeq ($(CONFIG_SKIP_SIGNAL_SCALE_MAPPING), y) EXTRA_CFLAGS += -DCONFIG_SKIP_SIGNAL_SCALE_MAPPING endif +ifeq ($(CONFIG_80211W), y) +EXTRA_CFLAGS += -DCONFIG_IEEE80211W +endif + ifeq ($(CONFIG_WOWLAN), y) EXTRA_CFLAGS += -DCONFIG_WOWLAN ifeq ($(CONFIG_SDIO_HCI), y) @@ -770,17 +789,35 @@ ifeq ($(CONFIG_GPIO_WAKEUP), y) EXTRA_CFLAGS += -DCONFIG_GPIO_WAKEUP endif +ifneq ($(CONFIG_WAKEUP_GPIO_IDX), default) +EXTRA_CFLAGS += -DWAKEUP_GPIO_IDX=$(CONFIG_WAKEUP_GPIO_IDX) +endif + ifeq ($(CONFIG_RTW_SDIO_PM_KEEP_POWER), y) ifeq ($(CONFIG_SDIO_HCI), y) EXTRA_CFLAGS += -DCONFIG_RTW_SDIO_PM_KEEP_POWER endif endif +ifeq ($(CONFIG_REDUCE_TX_CPU_LOADING), y) +EXTRA_CFLAGS += -DCONFIG_REDUCE_TX_CPU_LOADING +endif + +ifeq ($(CONFIG_BR_EXT), y) +BR_NAME = br0 +EXTRA_CFLAGS += -DCONFIG_BR_EXT +EXTRA_CFLAGS += '-DCONFIG_BR_EXT_BRNAME="'$(BR_NAME)'"' +endif + +ifeq ($(CONFIG_ANTENNA_DIVERSITY), y) +EXTRA_CFLAGS += -DCONFIG_ANTENNA_DIVERSITY +endif + + ifeq ($(CONFIG_PLATFORM_I386_PC), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE -EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT # only enable when kernel >= 3.2 +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT EXTRA_CFLAGS += -DCONFIG_P2P_IPS SUBARCH := $(shell uname -m | sed -e s/i.86/i386/) ARCH ?= $(SUBARCH) @@ -835,6 +872,19 @@ KSRC := /media/DATA-2/android-x86/ics-x86_20120130/out/target/product/generic_x8 MODULE_NAME :=wlan endif +ifeq ($(CONFIG_PLATFORM_ANDROID_INTEL_X86), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ANDROID_INTEL_X86 +EXTRA_CFLAGS += -DCONFIG_PLATFORM_INTEL_BYT +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +EXTRA_CFLAGS += -DCONFIG_P2P_IPS +EXTRA_CFLAGS += -DCONFIG_SKIP_SIGNAL_SCALE_MAPPING +ifeq ($(CONFIG_SDIO_HCI), y) +EXTRA_CFLAGS += -DCONFIG_RESUME_IN_WORKQUEUE +endif +endif + ifeq ($(CONFIG_PLATFORM_JB_X86), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE @@ -947,7 +997,7 @@ KSRC ?= /lib/modules/2.6.31-770-g0e46b52/source endif ifeq ($(CONFIG_PLATFORM_FS_MX61), y) -EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN ARCH := arm CROSS_COMPILE := /home/share/CusEnv/FreeScale/arm-eabi-4.4.3/bin/arm-eabi- KSRC ?= /home/share/CusEnv/FreeScale/FS_kernel_env @@ -966,6 +1016,7 @@ endif ifeq ($(CONFIG_PLATFORM_TI_DM365), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_TI_DM365 EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_RX +EXTRA_CFLAGS += -DCONFIG_SINGLE_XMIT_BUF -DCONFIG_SINGLE_RECV_BUF ARCH := arm #CROSS_COMPILE := /home/cnsd4/Appro/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/bin/arm_v5t_le- #KSRC := /home/cnsd4/Appro/mv_pro_5.0/montavista/pro/devkit/lsp/ti-davinci/linux-dm365 @@ -1041,9 +1092,9 @@ endif ifeq ($(CONFIG_PLATFORM_ARM_RK2818), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_ROCKCHIPS ARCH := arm -CROSS_COMPILE := /usr/src/release_fae_version/toolchain/arm-eabi-4.4.0/bin/arm-eabi- -KSRC := /usr/src/release_fae_version/kernel25_A7_281x -MODULE_NAME := wlan +#CROSS_COMPILE := /usr/src/release_fae_version/toolchain/arm-eabi-4.4.0/bin/arm-eabi- +#KSRC := /usr/src/release_fae_version/kernel25_A7_281x +MODULE_NAME := 8723bu endif ifeq ($(CONFIG_PLATFORM_ARM_RK3188), y) @@ -1051,14 +1102,11 @@ EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFO # default setting for Android 4.1, 4.2, 4.3, 4.4 EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE -# default setting for Power control -EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC -EXTRA_CFLAGS += -DRTW_SUPPORT_PLATFORM_SHUTDOWN # default setting for Special function EXTRA_CFLAGS += -DCONFIG_P2P_IPS ARCH := arm -CROSS_COMPILE := /home/android_sdk/Rockchip/Rk3188/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- -KSRC := /home/android_sdk/Rockchip/Rk3188/kernel +#CROSS_COMPILE := /home/android_sdk/Rockchip/Rk3188/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- +#KSRC := /home/android_sdk/Rockchip/Rk3188/kernel MODULE_NAME := 8723bu endif @@ -1108,7 +1156,7 @@ endif ifeq ($(CONFIG_PLATFORM_SZEBOOK), y) EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN ARCH:=arm -CROSS_COMPILE:=/opt/crosstool2/bin/armeb-unknown-linux-gnueabi- +CROSS_COMPILE:=/opt/crosstool2/bin/armeb-unknown-linux-gnueabi- KVER:= 2.6.31.6 KSRC:= ../code/linux-2.6.31.6-2020/ endif @@ -1242,6 +1290,7 @@ endif ifeq ($(CONFIG_PLATFORM_ACTIONS_ATV5201), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ACTIONS_ATV5201 +EXTRA_CFLAGS += -DCONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP ARCH := mips CROSS_COMPILE := mipsel-linux-gnu- KVER := $(KERNEL_VER) @@ -1301,7 +1350,39 @@ KSRC := /home/android_sdk/WonderMedia/wm8880-android4.4/kernel4.4/ MODULE_NAME :=8189es_kk endif -ifeq ($(CONFIG_MULTIDRV), y) +ifeq ($(CONFIG_PLATFORM_RTK119X), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +#EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN7I +EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +#EXTRA_CFLAGS += -DCONFIG_P2P_IPS -DCONFIG_QOS_OPTIMIZATION +EXTRA_CFLAGS += -DCONFIG_QOS_OPTIMIZATION + +#EXTRA_CFLAGS += -DCONFIG_#PLATFORM_OPS +ifeq ($(CONFIG_USB_HCI), y) +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX +#_PLATFORM_FILES += platform/platform_ARM_SUNxI_usb.o +endif +ifeq ($(CONFIG_SDIO_HCI), y) +_PLATFORM_FILES += platform/platform_ARM_SUNnI_sdio.o +endif + +ARCH := arm + +# ==== Cross compile setting for Android 4.4 SDK ===== +#CROSS_COMPILE := arm-linux-gnueabihf- +KVER := 3.10.24 +#KSRC :=/home/android_sdk/Allwinner/a20/android-kitkat44/lichee/linux-3.4 +CROSS_COMPILE := /home/realtek/software_phoenix/phoenix/toolchain/usr/local/arm-2013.11/bin/arm-linux-gnueabihf- +KSRC := /home/realtek/software_phoenix/linux-kernel +MODULE_NAME := 8192eu + +endif + + +ifeq ($(CONFIG_MULTIDRV), y) ifeq ($(CONFIG_SDIO_HCI), y) MODULE_NAME := rtw_sdio @@ -1318,6 +1399,7 @@ endif endif +USER_MODULE_NAME ?= ifneq ($(USER_MODULE_NAME),) MODULE_NAME := $(USER_MODULE_NAME) endif @@ -1357,7 +1439,7 @@ $(MODULE_NAME)-$(CONFIG_INTEL_WIDI) += core/rtw_intel_widi.o $(MODULE_NAME)-$(CONFIG_WAPI_SUPPORT) += core/rtw_wapi.o \ core/rtw_wapi_sms4.o - + $(MODULE_NAME)-y += $(_OS_INTFS_FILES) $(MODULE_NAME)-y += $(_HAL_INTFS_FILES) $(MODULE_NAME)-y += $(_OUTSRC_FILES) @@ -1407,7 +1489,7 @@ config_r: clean: cd hal/OUTSRC/ ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko - cd hal/OUTSRC/ ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd hal/OUTSRC/ ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko cd hal/led ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko cd hal ; rm -fr */*/*.mod.c */*/*.mod */*/*.o */*/.*.cmd */*/*.ko cd hal ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ap.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ap.c index 8362f94e834a..ca634367f4fe 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ap.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ap.c @@ -71,9 +71,9 @@ void free_mlme_ap_info(_adapter *padapter) //free bc/mc sta_info psta = rtw_get_bcmc_stainfo(padapter); - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(padapter, psta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); _rtw_spinlock_free(&pmlmepriv->bcn_update_lock); @@ -405,9 +405,9 @@ void expire_timeout_chk(_adapter *padapter) _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(padapter, psta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); } @@ -877,8 +877,6 @@ void update_bmc_sta(_adapter *padapter) if(psta) { psta->aid = 0;//default set to 0 - //psta->mac_id = psta->aid+4; - psta->mac_id = psta->aid + 1;//mac_id=1 for bc/mc stainfo pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; @@ -1031,7 +1029,7 @@ void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta) // B0 Config LDPC Coding Capability if (TEST_FLAG(phtpriv_ap->ldpc_cap, LDPC_HT_ENABLE_TX) && - GET_HT_CAPABILITY_ELE_LDPC_CAP((u8 *)(&phtpriv_sta->ht_cap))) + GET_HT_CAP_ELE_LDPC_CAP((u8 *)(&phtpriv_sta->ht_cap))) { SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX)); DBG_871X("Enable HT Tx LDPC for STA(%d)\n",psta->aid); @@ -1039,7 +1037,7 @@ void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta) // B7 B8 B9 Config STBC setting if (TEST_FLAG(phtpriv_ap->stbc_cap, STBC_HT_ENABLE_TX) && - GET_HT_CAPABILITY_ELE_RX_STBC((u8 *)(&phtpriv_sta->ht_cap))) + GET_HT_CAP_ELE_RX_STBC((u8 *)(&phtpriv_sta->ht_cap))) { SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX) ); DBG_871X("Enable HT Tx STBC for STA(%d)\n",psta->aid); @@ -1736,6 +1734,11 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor=MAX_AMPDU_FACTOR_64K; struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2); + if (0) { + DBG_871X(FUNC_ADPT_FMT" HT_CAP_IE from upper layer:\n", FUNC_ADPT_ARG(padapter)); + dump_ht_cap_ie_content(RTW_DBGDUMP, p+2, ie_len); + } + pHT_caps_ie=p; ht_cap = _TRUE; @@ -1743,6 +1746,7 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) rtw_ht_use_default_setting(padapter); + /* Update HT Capabilities Info field */ if (pmlmepriv->htpriv.sgi_20m == _FALSE) pht_cap->cap_info &= ~(IEEE80211_HT_CAP_SGI_20); @@ -1764,8 +1768,9 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) pht_cap->cap_info &= ~(IEEE80211_HT_CAP_RX_STBC_3R); } + /* Update A-MPDU Parameters field */ pht_cap->ampdu_params_info &= ~(IEEE80211_HT_CAP_AMPDU_FACTOR|IEEE80211_HT_CAP_AMPDU_DENSITY); - + if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) || (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) { @@ -1779,11 +1784,25 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & max_rx_ampdu_factor); //set Max Rx AMPDU size to 64K - rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); - if(rf_type == RF_1T1R) - { - pht_cap->supp_mcs_set[0] = 0xff; - pht_cap->supp_mcs_set[1] = 0x0; + /* Update Supported MCS Set field */ + { + int i; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + /* RX MCS Bitmask */ + switch(rf_type) + { + case RF_1T1R: + case RF_1T2R: //? + set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_1R); + break; + case RF_2T2R: + default: + set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_2R); + } + for (i = 0; i < 10; i++) + *(HT_CAP_ELE_RX_MCS_MAP(pht_cap)+i) &= padapter->mlmeextpriv.default_supported_mcs_set[i]; } #ifdef CONFIG_BEAMFORMING @@ -1813,7 +1832,11 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) #endif //CONFIG_BEAMFORMING _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len); - + + if (0) { + DBG_871X(FUNC_ADPT_FMT" HT_CAP_IE driver masked:\n", FUNC_ADPT_ARG(padapter)); + dump_ht_cap_ie_content(RTW_DBGDUMP, p+2, ie_len); + } } //parsing HT_INFO_IE @@ -2376,7 +2399,7 @@ static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui) } -void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx) +void _update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx, const char *tag) { _irqL irqL; struct mlme_priv *pmlmepriv; @@ -2454,6 +2477,8 @@ void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx) if(tx) { //send_beacon(padapter);//send_beacon must execute on TSR level + if (0) + DBG_871X(FUNC_ADPT_FMT" ie_id:%u - %s\n", FUNC_ADPT_ARG(padapter), ie_id, tag); set_tx_beacon_cmd(padapter); } #else @@ -2929,9 +2954,9 @@ u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reaso beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(padapter, psta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); return beacon_updated; @@ -2986,12 +3011,10 @@ int rtw_sta_flush(_adapter *padapter) struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; - DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); - if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) return ret; - + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); phead = &pstapriv->asoc_list; plist = get_next(phead); @@ -3192,6 +3215,15 @@ void start_ap_mode(_adapter *padapter) for(i=0; ista_aid[i] = NULL; +/* to avoid memory leak issue, don't set to NULL directly + pmlmepriv->wps_beacon_ie = NULL; + pmlmepriv->wps_probe_resp_ie = NULL; + pmlmepriv->wps_assoc_resp_ie = NULL; + + pmlmepriv->p2p_beacon_ie = NULL; + pmlmepriv->p2p_probe_resp_ie = NULL; +*/ + //for ACL _rtw_init_listhead(&(pacl_list->acl_node_q.queue)); pacl_list->num = 0; @@ -3218,6 +3250,7 @@ void stop_ap_mode(_adapter *padapter) pmlmepriv->update_bcn = _FALSE; pmlmeext->bstart_bss = _FALSE; + padapter->netif_up = _FALSE; //_rtw_spinlock_free(&pmlmepriv->bcn_update_lock); //reset and init security priv , this can refine with rtw_reset_securitypriv @@ -3253,9 +3286,9 @@ void stop_ap_mode(_adapter *padapter) rtw_free_all_stainfo(padapter); psta = rtw_get_bcmc_stainfo(padapter); - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(padapter, psta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_init_bcmc_stainfo(padapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_beamforming.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_beamforming.c index a3b44c3f503a..8d8c614e7b82 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_beamforming.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_beamforming.c @@ -330,7 +330,7 @@ BOOLEAN issue_ht_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx update_mgntframe_attrib(Adapter, pattrib); if (qidx == BCN_QUEUE_INX) - pattrib->qsel = 0x10; + pattrib->qsel = QSLT_BEACON; pattrib->rate = MGN_MCS8; pattrib->bwmode = bw; pattrib->order = 1; @@ -412,7 +412,7 @@ BOOLEAN issue_vht_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH b update_mgntframe_attrib(Adapter, pattrib); if (qidx == BCN_QUEUE_INX) - pattrib->qsel = 0x10; + pattrib->qsel = QSLT_BEACON; pattrib->rate = MGN_VHT2SS_MCS0; pattrib->bwmode = bw; pattrib->subtype = WIFI_NDPA; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_br_ext.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_br_ext.c index 88a517a68d7d..f90f790a31d8 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_br_ext.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_br_ext.c @@ -247,7 +247,7 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char if (len >= 8) { mac = scan_tlv(&data[8], len-8, 1, 1); if (mac) { - _DEBUG_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", + DBG_871X("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); memcpy(mac, replace_mac, 6); @@ -259,7 +259,7 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char if (len >= 16) { mac = scan_tlv(&data[16], len-16, 1, 1); if (mac) { - _DEBUG_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", + DBG_871X("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); memcpy(mac, replace_mac, 6); @@ -271,7 +271,7 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char if (len >= 24) { mac = scan_tlv(&data[24], len-24, 1, 1); if (mac) { - _DEBUG_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", + DBG_871X("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); memcpy(mac, replace_mac, 6); @@ -283,7 +283,7 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char if (len >= 24) { mac = scan_tlv(&data[24], len-24, 2, 1); if (mac) { - _DEBUG_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", + DBG_871X("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); memcpy(mac, replace_mac, 6); @@ -295,7 +295,7 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char if (len >= 40) { mac = scan_tlv(&data[40], len-40, 2, 1); if (mac) { - _DEBUG_INFO("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", + DBG_871X("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); memcpy(mac, replace_mac, 6); @@ -439,7 +439,7 @@ static int __nat25_db_network_lookup_and_replace(_adapter *priv, atomic_inc(&db->use_count); #ifdef CL_IPV6_PASS - DEBUG_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" + DBG_871X("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "%02x%02x%02x%02x%02x%02x\n", db->macAddr[0], db->macAddr[1], @@ -465,7 +465,7 @@ static int __nat25_db_network_lookup_and_replace(_adapter *priv, db->networkAddr[15], db->networkAddr[16]); #else - DEBUG_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + DBG_871X("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", db->macAddr[0], db->macAddr[1], db->macAddr[2], @@ -815,7 +815,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) //in class A, B, C, host address is all zero or all one is illegal if (iph->saddr == 0) return 0; - DEBUG_INFO("NAT25: Insert IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); + DBG_871X("NAT25: Insert IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); __nat25_generate_ipv4_network_addr(networkAddr, &iph->saddr); //record source IP address and , source mac address into db __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); @@ -826,7 +826,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_LOOKUP: { - DEBUG_INFO("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); + DBG_871X("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); #ifdef SUPPORT_TX_MCAST2UNI if (priv->pshare->rf_ft_var.mc2u_disable || ((((OPMODE & (WIFI_STATION_STATE|WIFI_ASOC_STATE)) @@ -840,12 +840,12 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) { if (*((unsigned char *)&iph->daddr + 3) == 0xff) { // L2 is unicast but L3 is broadcast, make L2 bacome broadcast - DEBUG_INFO("NAT25: Set DA as boardcast\n"); + DBG_871X("NAT25: Set DA as boardcast\n"); memset(skb->data, 0xff, ETH_ALEN); } else { // forward unknow IP packet to upper TCP/IP - DEBUG_INFO("NAT25: Replace DA with BR's MAC\n"); + DBG_871X("NAT25: Replace DA with BR's MAC\n"); if ( (*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac+4)) == 0 ) { void netdev_br_init(struct net_device *netdev); printk("Re-init netdev_br_init() due to br_mac==0!\n"); @@ -885,7 +885,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_INSERT: { - DEBUG_INFO("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], + DBG_871X("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]); // change to ARP sender mac address to wlan STA address @@ -904,7 +904,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_LOOKUP: { - DEBUG_INFO("NAT25: Lookup ARP\n"); + DBG_871X("NAT25: Lookup ARP\n"); arp_ptr += arp->ar_hln; sender = (unsigned int *)arp_ptr; @@ -930,8 +930,9 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) /*---------------------------------------------------*/ /* Handle IPX and Apple Talk frame */ /*---------------------------------------------------*/ - else if((protocol == __constant_htons(ETH_P_IPX)) || - (protocol <= __constant_htons(ETH_FRAME_LEN))) + else if((protocol == __constant_htons(ETH_P_IPX)) || + (protocol == __constant_htons(ETH_P_ATALK)) || + (protocol == __constant_htons(ETH_P_AARP))) { unsigned char ipx_header[2] = {0xFF, 0xFF}; struct ipxhdr *ipx = NULL; @@ -941,14 +942,14 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) if(protocol == __constant_htons(ETH_P_IPX)) { - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet II)\n"); + DBG_871X("NAT25: Protocol=IPX (Ethernet II)\n"); ipx = (struct ipxhdr *)framePtr; } - else if(protocol <= __constant_htons(ETH_FRAME_LEN)) + else //if(protocol <= __constant_htons(ETH_FRAME_LEN)) { if(!memcmp(ipx_header, framePtr, 2)) { - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.3)\n"); + DBG_871X("NAT25: Protocol=IPX (Ethernet 802.3)\n"); ipx = (struct ipxhdr *)framePtr; } else @@ -968,7 +969,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) { framePtr += 5; // eliminate the SNAP header - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet SNAP)\n"); + DBG_871X("NAT25: Protocol=IPX (Ethernet SNAP)\n"); ipx = (struct ipxhdr *)framePtr; } else if(!memcmp(aarp_snap_id, framePtr, 5)) @@ -996,18 +997,14 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) if(!memcmp(ipx_header, framePtr, 2)) { - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.2)\n"); + DBG_871X("NAT25: Protocol=IPX (Ethernet 802.2)\n"); ipx = (struct ipxhdr *)framePtr; } else return -1; } - else - return -1; } } - else - return -1; /* IPX */ if(ipx != NULL) @@ -1017,14 +1014,14 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_CHECK: if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { - DEBUG_INFO("NAT25: Check IPX skb_copy\n"); + DBG_871X("NAT25: Check IPX skb_copy\n"); return 0; } return -1; case NAT25_INSERT: { - DEBUG_INFO("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n", + DBG_871X("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n", ipx->ipx_dest.net, ipx->ipx_dest.node[0], ipx->ipx_dest.node[1], @@ -1044,7 +1041,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { - DEBUG_INFO("NAT25: Use IPX Net, and Socket as network addr\n"); + DBG_871X("NAT25: Use IPX Net, and Socket as network addr\n"); __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock); @@ -1066,7 +1063,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) { if(!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) { - DEBUG_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n"); + DBG_871X("NAT25: Lookup IPX, Modify Destination IPX Node addr\n"); __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock); @@ -1109,7 +1106,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) // change to AARP source mac address to wlan STA address memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN); - DEBUG_INFO("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n", + DBG_871X("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n", ea->pa_src_net, ea->pa_src_node, ea->pa_dst_net, @@ -1125,7 +1122,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_LOOKUP: { - DEBUG_INFO("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", + DBG_871X("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", ea->pa_src_net, ea->pa_src_node, ea->pa_dst_net, @@ -1155,7 +1152,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_INSERT: { - DEBUG_INFO("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", + DBG_871X("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", ddp->deh_snet, ddp->deh_snode, ddp->deh_dnet, @@ -1171,7 +1168,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_LOOKUP: { - DEBUG_INFO("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", + DBG_871X("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", ddp->deh_snet, ddp->deh_snode, ddp->deh_dnet, @@ -1248,7 +1245,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) if(__nat25_add_pppoe_tag(skb, tag) < 0) return -1; - DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n", + DBG_871X("NAT25: Insert PPPoE, forward %s packet\n", (ph->code == PADI_CODE ? "PADI" : "PADR")); } else { // not add relay tag @@ -1269,7 +1266,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) } else // session phase { - DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); + DBG_871X("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid)); @@ -1327,7 +1324,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) if (offset > 0) tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN); - DEBUG_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n", + DBG_871X("NAT25: Lookup PPPoE, forward %s Packet from %s\n", (ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name); } else { // not add relay tag @@ -1342,7 +1339,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) else { if(ph->sid != 0) { - DEBUG_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name); + DBG_871X("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name); __nat25_generate_pppoe_network_addr(networkAddr, skb->data+ETH_ALEN, &(ph->sid)); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); @@ -1426,7 +1423,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) case NAT25_INSERT: { - DEBUG_INFO("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," + DBG_871X("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3], iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7], @@ -1455,7 +1452,7 @@ int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) return 0; case NAT25_LOOKUP: - DEBUG_INFO("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," + DBG_871X("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3], iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7], @@ -1571,7 +1568,7 @@ void mac_clone(_adapter *priv, unsigned char *addr) struct sockaddr sa; memcpy(sa.sa_data, addr, ETH_ALEN); - DEBUG_INFO("MAC Clone: Addr=%02x%02x%02x%02x%02x%02x\n", + DBG_871X("MAC Clone: Addr=%02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); rtl8192cd_set_hwaddr(priv->dev, &sa); } @@ -1650,7 +1647,7 @@ void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb) { register int sum = 0; - DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n"); + DBG_871X("DHCP: change flag of DHCP request to broadcast.\n"); // or BROADCAST flag dhcph->flags |= htons(BROADCAST_FLAG); // recalculate checksum diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_bt_mp.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_bt_mp.c index c9554f75f6cf..73f2105beced 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_bt_mp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_bt_mp.c @@ -107,10 +107,6 @@ mptbt_CheckC2hFrame( return c2hStatus; } -#if defined(CONFIG_RTL8723A) -extern s32 FillH2CCmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); -#endif - BT_CTRL_STATUS mptbt_SendH2c( PADAPTER Adapter, @@ -140,7 +136,7 @@ mptbt_SendH2c( pMptCtx->MptBtC2hEvent = _FALSE; #if defined(CONFIG_RTL8723A) - FillH2CCmd(Adapter, 70, h2cCmdLen, (pu1Byte)pH2c); + rtw_hal_fill_h2c_cmd(Adapter, 70, h2cCmdLen, (pu1Byte)pH2c); #elif defined(CONFIG_RTL8723B) rtl8723b_set_FwBtMpOper_cmd(Adapter, pH2c->opCode, pH2c->opCodeVer, pH2c->reqNum, pH2c->buf); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_btcoex.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_btcoex.c index d37f5c817eb4..157b8757066a 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_btcoex.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_btcoex.c @@ -33,6 +33,11 @@ void rtw_btcoex_PowerOnSetting(PADAPTER padapter) hal_btcoex_PowerOnSetting(padapter); } +void rtw_btcoex_PreLoadFirmware(PADAPTER padapter) +{ + hal_btcoex_PreLoadFirmware(padapter); +} + void rtw_btcoex_HAL_Initialize(PADAPTER padapter, u8 bWifiOnly) { hal_btcoex_InitHwConfig(padapter, bWifiOnly); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_cmd.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_cmd.c index 2298e424e8d0..6ed8f22b4947 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_cmd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_cmd.c @@ -209,6 +209,9 @@ since only spin_lock is used. ISR/Call-Back functions can't call this sub-function. */ +#ifdef DBG_CMD_QUEUE +extern u8 dump_cmd_id; +#endif sint _rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj) { @@ -219,11 +222,52 @@ _func_enter_; if (obj == NULL) goto exit; + if(obj->cmdsz > MAX_CMDSZ ){ + DBG_871X("%s failed due to obj->cmdsz(%d) > MAX_CMDSZ(%d) \n",__FUNCTION__, obj->cmdsz,MAX_CMDSZ); + goto exit; + } //_enter_critical_bh(&queue->lock, &irqL); _enter_critical(&queue->lock, &irqL); rtw_list_insert_tail(&obj->list, &queue->queue); + #ifdef DBG_CMD_QUEUE + if(dump_cmd_id){ + printk("%s===> cmdcode:0x%02x\n",__FUNCTION__,obj->cmdcode); + if(obj->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT)){ + if(obj->parmbuf){ + struct C2HEvent_Header *pc2h_evt_hdr = (struct C2HEvent_Header *)(obj->parmbuf); + printk("pc2h_evt_hdr->ID:0x%02x(%d)\n",pc2h_evt_hdr->ID,pc2h_evt_hdr->ID); + } + } + if(obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)){ + if(obj->parmbuf){ + struct drvextra_cmd_parm *pdrvextra_cmd_parm =(struct drvextra_cmd_parm*)(obj->parmbuf); + printk("pdrvextra_cmd_parm->ec_id:0x%02x\n",pdrvextra_cmd_parm->ec_id); + } + } + } + + if (queue->queue.prev->next != &queue->queue) + { + DBG_871X("[%d] head %p, tail %p, tail->prev->next %p[tail], tail->next %p[head]\n", __LINE__, + &queue->queue, queue->queue.prev, queue->queue.prev->prev->next, queue->queue.prev->next); + + DBG_871X("==========%s============\n",__FUNCTION__); + DBG_871X("head:%p,obj_addr:%p\n",&queue->queue,obj); + DBG_871X("padapter: %p\n",obj->padapter); + DBG_871X("cmdcode: 0x%02x\n",obj->cmdcode); + DBG_871X("res: %d\n",obj->res); + DBG_871X("parmbuf: %p\n",obj->parmbuf); + DBG_871X("cmdsz: %d\n",obj->cmdsz); + DBG_871X("rsp: %p\n",obj->rsp); + DBG_871X("rspsz: %d\n",obj->rspsz); + DBG_871X("sctx: %p\n",obj->sctx); + DBG_871X("list->next: %p\n",obj->list.next); + DBG_871X("list->prev: %p\n",obj->list.prev); + } + #endif //DBG_CMD_QUEUE + //_exit_critical_bh(&queue->lock, &irqL); _exit_critical(&queue->lock, &irqL); @@ -243,11 +287,51 @@ _func_enter_; //_enter_critical_bh(&(queue->lock), &irqL); _enter_critical(&queue->lock, &irqL); - if (rtw_is_list_empty(&(queue->queue))) + + #ifdef DBG_CMD_QUEUE + if (queue->queue.prev->next != &queue->queue) + { + DBG_871X("[%d] head %p, tail %p, tail->prev->next %p[tail], tail->next %p[head]\n", __LINE__, + &queue->queue, queue->queue.prev, queue->queue.prev->prev->next, queue->queue.prev->next); + } + #endif //DBG_CMD_QUEUE + + + if (rtw_is_list_empty(&(queue->queue))){ obj = NULL; + } else { obj = LIST_CONTAINOR(get_next(&(queue->queue)), struct cmd_obj, list); + + #ifdef DBG_CMD_QUEUE + if (queue->queue.prev->next != &queue->queue){ + DBG_871X("==========%s============\n",__FUNCTION__); + DBG_871X("head:%p,obj_addr:%p\n",&queue->queue,obj); + DBG_871X("padapter: %p\n",obj->padapter); + DBG_871X("cmdcode: 0x%02x\n",obj->cmdcode); + DBG_871X("res: %d\n",obj->res); + DBG_871X("parmbuf: %p\n",obj->parmbuf); + DBG_871X("cmdsz: %d\n",obj->cmdsz); + DBG_871X("rsp: %p\n",obj->rsp); + DBG_871X("rspsz: %d\n",obj->rspsz); + DBG_871X("sctx: %p\n",obj->sctx); + DBG_871X("list->next: %p\n",obj->list.next); + DBG_871X("list->prev: %p\n",obj->list.prev); + } + + if(dump_cmd_id){ + DBG_871X("%s===> cmdcode:0x%02x\n",__FUNCTION__,obj->cmdcode); + if(obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)){ + if(obj->parmbuf){ + struct drvextra_cmd_parm *pdrvextra_cmd_parm =(struct drvextra_cmd_parm*)(obj->parmbuf); + printk("pdrvextra_cmd_parm->ec_id:0x%02x\n",pdrvextra_cmd_parm->ec_id); + } + } + + } + #endif //DBG_CMD_QUEUE + rtw_list_delete(&obj->list); } @@ -404,14 +488,16 @@ _func_exit_; void rtw_free_cmd_obj(struct cmd_obj *pcmd) { + struct drvextra_cmd_parm *extra_parm = NULL; _func_enter_; - if((pcmd->cmdcode!=_JoinBss_CMD_) &&(pcmd->cmdcode!= _CreateBss_CMD_)) - { - //free parmbuf in cmd_obj - rtw_mfree((unsigned char*)pcmd->parmbuf, pcmd->cmdsz); - } - + if(pcmd->parmbuf != NULL){ + if((pcmd->cmdcode!=_JoinBss_CMD_) &&(pcmd->cmdcode!= _CreateBss_CMD_)) + { + //free parmbuf in cmd_obj + rtw_mfree((unsigned char*)pcmd->parmbuf, pcmd->cmdsz); + } + } if(pcmd->rsp!=NULL) { if(pcmd->rspsz!= 0) @@ -452,7 +538,7 @@ thread_return rtw_cmd_thread(thread_context context) PADAPTER padapter = (PADAPTER)context; struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); struct drvextra_cmd_parm *extra_parm = NULL; - + _irqL irqL; _func_enter_; thread_enter("RTW_CMD_THREAD"); @@ -485,11 +571,14 @@ _func_enter_; break; } + _enter_critical(&pcmdpriv->cmd_queue.lock, &irqL); if(rtw_is_list_empty(&(pcmdpriv->cmd_queue.queue))) { //DBG_871X("%s: cmd queue is empty!\n", __func__); + _exit_critical(&pcmdpriv->cmd_queue.lock, &irqL); continue; } + _exit_critical(&pcmdpriv->cmd_queue.lock, &irqL); #ifdef CONFIG_LPS_LCLK if (rtw_register_cmd_alive(padapter) != _SUCCESS) @@ -520,6 +609,11 @@ _next: if( _FAIL == rtw_cmd_filter(pcmdpriv, pcmd) ) { pcmd->res = H2C_DROPPED; + if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf; + if (extra_parm && extra_parm->pbuf && extra_parm->size > 0) + rtw_mfree(extra_parm->pbuf, extra_parm->size); + } goto post_process; } @@ -527,6 +621,10 @@ _next: pcmd->cmdsz = _RND4((pcmd->cmdsz));//_RND4 + if(pcmd->cmdsz > MAX_CMDSZ ){ + DBG_871X("%s cmdsz:%d > MAX_CMDSZ:%d\n",__FUNCTION__,pcmd->cmdsz,MAX_CMDSZ); + } + _rtw_memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); if(pcmd->cmdcode < (sizeof(wlancmds) /sizeof(struct cmd_hdl))) @@ -618,7 +716,6 @@ post_process: #endif break; } - //DBG_871X("%s: leaving... drop cmdcode:%u size:%d\n", __FUNCTION__, pcmd->cmdcode, pcmd->cmdsz); if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { @@ -1345,6 +1442,8 @@ _func_enter_; } } + pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); + psecnetwork=(WLAN_BSSID_EX *)&psecuritypriv->sec_bss; if(psecnetwork==NULL) { @@ -1416,7 +1515,7 @@ _func_enter_; { rtw_ht_use_default_setting(padapter); - rtw_build_wmm_ie_ht(padapter, &psecnetwork->IEs[12], &psecnetwork->IELength); + rtw_build_wmm_ie_ht(padapter, &psecnetwork->IEs[0], &psecnetwork->IELength); //rtw_restructure_ht_ie rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[12], &psecnetwork->IEs[0], @@ -1437,8 +1536,6 @@ _func_enter_; #endif //CONFIG_80211N_HT - pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); - #if 0 psecuritypriv->supplicant_ie[0]=(u8)psecnetwork->IELength; @@ -2282,6 +2379,7 @@ static void collect_traffic_statistics(_adapter *padapter) pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes *8/2/1024/1024); } +//from_timer == 1 means driver is in LPS u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer) { u8 bEnterPS = _FALSE; @@ -2372,11 +2470,16 @@ u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer) #ifdef CONFIG_LPS // check traffic for powersaving. if( ((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || - (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) +#ifdef CONFIG_LPS_SLOW_TRANSITION + (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) +#else //CONFIG_LPS_SLOW_TRANSITION + (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4) +#endif //CONFIG_LPS_SLOW_TRANSITION + ) { //DBG_871X("(-)Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); bEnterPS= _FALSE; - +#ifdef CONFIG_LPS_SLOW_TRANSITION if(bBusyTraffic == _TRUE) { if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount <= 4) @@ -2391,11 +2494,13 @@ u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer) pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 30; } } +#endif //CONFIG_LPS_SLOW_TRANSITION + } else { //DBG_871X("(+)Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); - +#ifdef CONFIG_LPS_SLOW_TRANSITION if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount>=2) pmlmepriv->LinkDetectInfo.TrafficTransitionCount -=2; else @@ -2403,6 +2508,9 @@ u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer) if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount == 0) bEnterPS= _TRUE; +#else //CONFIG_LPS_SLOW_TRANSITION + bEnterPS= _TRUE; +#endif //CONFIG_LPS_SLOW_TRANSITION } #ifdef CONFIG_DYNAMIC_DTIM @@ -2519,7 +2627,7 @@ void dynamic_chk_wk_hdl(_adapter *padapter) //if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)==_FALSE) { - linked_status_chk(padapter); + linked_status_chk(padapter, 0); traffic_status_watchdog(padapter, 0); dm_DynamicUsbTxAgg(padapter, 0); } @@ -2614,6 +2722,16 @@ _func_enter_; break; case LPS_CTRL_TRAFFIC_BUSY: LPS_Leave(padapter, "LPS_CTRL_TRAFFIC_BUSY"); + break; + case LPS_CTRL_TX_TRAFFIC_LEAVE: + LPS_Leave(padapter, "LPS_CTRL_TX_TRAFFIC_LEAVE"); + break; + case LPS_CTRL_RX_TRAFFIC_LEAVE: + LPS_Leave(padapter, "LPS_CTRL_RX_TRAFFIC_LEAVE"); + break; + case LPS_CTRL_ENTER: + LPS_Enter(padapter, "TRAFFIC_IDLE_1"); + break; default: break; } @@ -3043,8 +3161,6 @@ _func_exit_; #ifdef CONFIG_AP_MODE -extern u32 g_wait_hiq_empty; - static void rtw_chk_hi_queue_hdl(_adapter *padapter) { struct sta_info *psta_bmc; @@ -3058,7 +3174,7 @@ static void rtw_chk_hi_queue_hdl(_adapter *padapter) rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); - while(_FALSE == empty && rtw_get_passing_time_ms(start) < g_wait_hiq_empty) + while(_FALSE == empty && rtw_get_passing_time_ms(start) < rtw_get_wait_hiq_empty_ms()) { rtw_msleep_os(100); rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); @@ -3077,7 +3193,7 @@ static void rtw_chk_hi_queue_hdl(_adapter *padapter) pstapriv->sta_dz_bitmap &= ~BIT(0); if (update_tim == _TRUE) - update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "bmc sleepq and HIQ empty"); } else //re check again { @@ -3338,6 +3454,42 @@ exit: } //#endif //CONFIG_C2H_PACKET_EN +u8 rtw_run_in_thread_cmd(PADAPTER padapter, void (*func)(void*), void* context) +{ + struct cmd_priv *pcmdpriv; + struct cmd_obj *ph2c; + struct RunInThread_param *parm; + s32 res = _SUCCESS; + +_func_enter_; + + pcmdpriv = &padapter->cmdpriv; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (NULL == ph2c) { + res = _FAIL; + goto exit; + } + + parm = (struct RunInThread_param*)rtw_zmalloc(sizeof(struct RunInThread_param)); + if (NULL == parm) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + parm->func = func; + parm->context = context; + init_h2fwcmd_w_parm_no_rsp(ph2c, parm, GEN_CMD_CODE(_RunInThreadCMD)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: + +_func_exit_; + + return res; +} + s32 c2h_evt_hdl(_adapter *adapter, u8 *c2h_evt, c2h_id_filter filter) { s32 ret = _FAIL; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_debug.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_debug.c index 936d2e395df1..72cad7378d2c 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_debug.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_debug.c @@ -151,6 +151,51 @@ void rf_reg_dump(void *sel, _adapter *adapter) } } +static u8 fwdl_test_chksum_fail = 0; +static u8 fwdl_test_wintint_rdy_fail = 0; + +bool rtw_fwdl_test_trigger_chksum_fail() +{ + if (fwdl_test_chksum_fail) { + DBG_871X_LEVEL(_drv_always_, "fwdl test case: trigger chksum_fail\n"); + fwdl_test_chksum_fail--; + return _TRUE; + } + return _FALSE; +} + +bool rtw_fwdl_test_trigger_wintint_rdy_fail() +{ + if (fwdl_test_wintint_rdy_fail) { + DBG_871X_LEVEL(_drv_always_, "fwdl test case: trigger wintint_rdy_fail\n"); + fwdl_test_wintint_rdy_fail--; + return _TRUE; + } + return _FALSE; +} + +static u32 g_wait_hiq_empty_ms = 0; + +u32 rtw_get_wait_hiq_empty_ms() +{ + return g_wait_hiq_empty_ms; +} + +void rtw_sink_rtp_seq_dbg( _adapter *adapter,_pkt *pkt) +{ + struct recv_priv *precvpriv = &(adapter->recvpriv); + if( precvpriv->sink_udpport > 0) + { + if(*((u16*)((pkt->data)+0x24)) == cpu_to_be16(precvpriv->sink_udpport)) + { + precvpriv->pre_rtp_rxseq= precvpriv->cur_rtp_rxseq; + precvpriv->cur_rtp_rxseq = be16_to_cpu(*((u16*)((pkt->data)+0x2C))); + if( precvpriv->pre_rtp_rxseq+1 != precvpriv->cur_rtp_rxseq) + DBG_871X("%s : RTP Seq num from %d to %d\n",__FUNCTION__,precvpriv->pre_rtp_rxseq,precvpriv->cur_rtp_rxseq); + } + } +} + #ifdef CONFIG_PROC_DEBUG ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { @@ -471,8 +516,10 @@ int proc_get_survey_info(struct seq_file *m, void *v) _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); phead = get_list_head(queue); + if(!phead) + return 0; plist = get_next(phead); - if ((!phead) || (!plist)) + if (!plist) return 0; DBG_871X_SEL_NL(m, "%5s %-17s %3s %-3s %-4s %-4s %5s %s\n","index", "bssid", "ch", "RSSI", "SdBm", "Noise", "age", "ssid"); @@ -591,6 +638,8 @@ int proc_get_trx_info(struct seq_file *m, void *v) struct recv_priv *precvpriv = &padapter->recvpriv; struct hw_xmit *phwxmit; + dump_os_queue(m, padapter); + DBG_871X_SEL_NL(m, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d\n" , pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt); DBG_871X_SEL_NL(m, "free_ext_xmitbuf_cnt=%d, free_xframe_ext_cnt=%d\n" @@ -605,21 +654,60 @@ int proc_get_trx_info(struct seq_file *m, void *v) } #ifdef CONFIG_USB_HCI - DBG_871X_SEL_NL(m, "rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt); + DBG_871X_SEL_NL(m, "rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt))); #endif return 0; } +int proc_get_dis_pwt(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 dis_pwt = 0; + rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DIS_PWT, &(dis_pwt)); + DBG_871X_SEL_NL(m, " Tx Power training mode:%s \n",(dis_pwt==_TRUE)?"Disable":"Enable"); + return 0; +} +ssize_t proc_set_dis_pwt(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[4]={0}; + u8 dis_pwt = 0; + + if (count < 1) + return -EFAULT; + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%hhx", &dis_pwt); + DBG_871X("Set Tx Power training mode:%s \n",(dis_pwt==_TRUE)?"Disable":"Enable"); + + if (num >= 1) + rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DIS_PWT, &(dis_pwt)); + } + + return count; + +} + int proc_get_rate_ctl(struct seq_file *m, void *v) { struct net_device *dev = m->private; int i; _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); - + u8 data_rate = 0, sgi=0, data_fb = 0; + if (adapter->fix_rate != 0xff) { - DBG_871X_SEL_NL(m, "FIX\n"); - DBG_871X_SEL_NL(m, "0x%02x(%s)\n", adapter->fix_rate, HDATA_RATE(adapter->fix_rate)); + data_rate = adapter->fix_rate & 0x7F; + sgi = adapter->fix_rate >>7; + data_fb = adapter->data_fb?1:0; + DBG_871X_SEL_NL(m, "FIXED %s%s%s\n" + , HDATA_RATE(data_rate) + , sgi?" SGI":" LGI" + , data_fb?" FB":"" + ); + DBG_871X_SEL_NL(m, "0x%02x %u\n", adapter->fix_rate, adapter->data_fb); } else { DBG_871X_SEL_NL(m, "RA\n"); } @@ -633,24 +721,24 @@ ssize_t proc_set_rate_ctl(struct file *file, const char __user *buffer, size_t c _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); char tmp[32]; u8 fix_rate; + u8 data_fb; if (count < 1) return -EFAULT; if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - int num = sscanf(tmp, "%hhx", &fix_rate); + int num = sscanf(tmp, "%hhx %hhu", &fix_rate, &data_fb); if (num >= 1) adapter->fix_rate = fix_rate; + if (num >= 2) + adapter->data_fb = data_fb?1:0; } return count; } -u8 g_fwdl_chksum_fail = 0; -u8 g_fwdl_wintint_rdy_fail = 0; - ssize_t proc_set_fwdl_test_case(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -661,14 +749,12 @@ ssize_t proc_set_fwdl_test_case(struct file *file, const char __user *buffer, si return -EFAULT; if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - int num = sscanf(tmp, "%hhu %hhu", &g_fwdl_chksum_fail, &g_fwdl_wintint_rdy_fail); + int num = sscanf(tmp, "%hhu %hhu", &fwdl_test_chksum_fail, &fwdl_test_wintint_rdy_fail); } return count; } -u32 g_wait_hiq_empty = 0; - ssize_t proc_set_wait_hiq_empty(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -679,7 +765,7 @@ ssize_t proc_set_wait_hiq_empty(struct file *file, const char __user *buffer, si return -EFAULT; if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - int num = sscanf(tmp, "%u", &g_wait_hiq_empty); + int num = sscanf(tmp, "%u", &g_wait_hiq_empty_ms); } return count; @@ -987,6 +1073,19 @@ int proc_get_int_logs(struct seq_file *m, void *v) #endif // CONFIG_DBG_COUNTER +int proc_get_hw_status(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = padapter->dvobj; + struct debug_priv *pdbgpriv = &dvobj->drv_dbg; + + DBG_871X_SEL_NL(m, "RX FIFO full count: last_time=%lld, current_time=%lld, differential=%lld\n" + , pdbgpriv->dbg_rx_fifo_last_overflow, pdbgpriv->dbg_rx_fifo_curr_overflow, pdbgpriv->dbg_rx_fifo_diff_overflow); + + return 0; +} + int proc_get_rx_signal(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -1005,20 +1104,6 @@ int proc_get_rx_signal(struct seq_file *m, void *v) return 0; } - -int proc_get_hw_status(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); - struct dvobj_priv *dvobj = padapter->dvobj; - struct debug_priv *pdbgpriv = &dvobj->drv_dbg; - - DBG_871X_SEL_NL(m, "RX FIFO full count: last_time=%lld, current_time=%lld, differential=%lld\n" - , pdbgpriv->dbg_rx_fifo_last_overflow, pdbgpriv->dbg_rx_fifo_curr_overflow, pdbgpriv->dbg_rx_fifo_diff_overflow); - - return 0; -} - ssize_t proc_set_rx_signal(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -1082,10 +1167,10 @@ ssize_t proc_set_ht_enable(struct file *file, const char __user *buffer, size_t int num = sscanf(tmp, "%d ", &mode); - if( pregpriv && mode >= 0 && mode < 2 ) + if( pregpriv && mode < 2 ) { pregpriv->ht_enable= mode; - printk("ht_enable=%d\n", pregpriv->ht_enable); + DBG_871X("ht_enable=%d\n", pregpriv->ht_enable); } } @@ -1205,7 +1290,7 @@ ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t c int num = sscanf(tmp, "%d ", &mode); - if( pregpriv && mode >= 0 && mode < 2 ) + if( pregpriv && mode < 2 ) { pmlmeinfo->bAcceptAddbaReq = mode; DBG_871X("pmlmeinfo->bAcceptAddbaReq=%d \n",pmlmeinfo->bAcceptAddbaReq); @@ -1220,7 +1305,135 @@ ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t c return count; } +int proc_get_rx_ampdu_factor(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + + if(padapter) + { + DBG_871X_SEL_NL(m,"rx ampdu factor = %x\n",padapter->driver_rx_ampdu_factor); + } + + return 0; +} + +ssize_t proc_set_rx_ampdu_factor(struct file *file, const char __user *buffer + , size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 factor; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + + int num = sscanf(tmp, "%d ", &factor); + + if( padapter && (num == 1) ) + { + DBG_871X("padapter->driver_rx_ampdu_factor = %x\n", factor); + + if(factor > 0x03) + padapter->driver_rx_ampdu_factor = 0xFF; + else + padapter->driver_rx_ampdu_factor = factor; + } + } + + return count; +} + +int proc_get_rx_ampdu_density(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + + if(padapter) + { + DBG_871X_SEL_NL(m,"rx ampdu densityg = %x\n",padapter->driver_rx_ampdu_spacing); + } + + return 0; +} + +ssize_t proc_set_rx_ampdu_density(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 density; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + + int num = sscanf(tmp, "%d ", &density); + + if( padapter && (num == 1) ) + { + DBG_871X("padapter->driver_rx_ampdu_spacing = %x\n", density); + + if(density > 0x07) + padapter->driver_rx_ampdu_spacing = 0xFF; + else + padapter->driver_rx_ampdu_spacing = density; + } + } + + return count; +} + +int proc_get_tx_ampdu_density(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + + if(padapter) + { + DBG_871X_SEL_NL(m,"tx ampdu density = %x\n",padapter->driver_ampdu_spacing); + } + + return 0; +} + +ssize_t proc_set_tx_ampdu_density(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 density; + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + + int num = sscanf(tmp, "%d ", &density); + + if( padapter && (num == 1) ) + { + DBG_871X("padapter->driver_ampdu_spacing = %x\n", density); + + if(density > 0x07) + padapter->driver_ampdu_spacing = 0xFF; + else + padapter->driver_ampdu_spacing = density; + } + } + + return count; +} #endif //CONFIG_80211N_HT int proc_get_en_fwps(struct seq_file *m, void *v) @@ -1255,7 +1468,7 @@ ssize_t proc_set_en_fwps(struct file *file, const char __user *buffer, size_t co int num = sscanf(tmp, "%d ", &mode); - if( pregpriv && mode >= 0 && mode < 2 ) + if( pregpriv && mode < 2 ) { pregpriv->check_fw_ps = mode; DBG_871X("pregpriv->check_fw_ps=%d \n",pregpriv->check_fw_ps); @@ -1319,13 +1532,14 @@ ssize_t proc_set_rx_stbc(struct file *file, const char __user *buffer, size_t co } #endif //CONFIG_80211N_HT -int proc_get_rssi_disp(struct seq_file *m, void *v) +/*int proc_get_rssi_disp(struct seq_file *m, void *v) { struct net_device *dev = m->private; return 0; } +*/ -ssize_t proc_set_rssi_disp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +/*ssize_t proc_set_rssi_disp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); @@ -1364,7 +1578,7 @@ ssize_t proc_set_rssi_disp(struct file *file, const char __user *buffer, size_t } - +*/ #ifdef CONFIG_AP_MODE int proc_get_all_sta_info(struct seq_file *m, void *v) @@ -1479,7 +1693,7 @@ int proc_get_best_channel(struct seq_file *m, void *v) index_5G = i; } - for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) { + for (i=0; (i < MAX_CHANNEL_NUM) && (pmlmeext->channel_set[i].ChannelNum !=0) ; i++) { // 2.4G if ( pmlmeext->channel_set[i].ChannelNum == 6 ) { if ( pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count ) { @@ -1766,8 +1980,65 @@ int proc_get_tx_ring(struct seq_file *m, void *v) return 0; } - #endif +#ifdef CONFIG_P2P_WOWLAN +int proc_get_p2p_wowlan_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + struct p2p_wowlan_info peerinfo = pwdinfo->p2p_wow_info; + if(_TRUE == peerinfo.is_trigger) + { + DBG_871X_SEL_NL(m,"is_trigger: TRUE\n"); + switch(peerinfo.wowlan_recv_frame_type) + { + case P2P_WOWLAN_RECV_NEGO_REQ: + DBG_871X_SEL_NL(m,"Frame Type: Nego Request\n"); + break; + case P2P_WOWLAN_RECV_INVITE_REQ: + DBG_871X_SEL_NL(m,"Frame Type: Invitation Request\n"); + break; + case P2P_WOWLAN_RECV_PROVISION_REQ: + DBG_871X_SEL_NL(m,"Frame Type: Provision Request\n"); + break; + default: + break; + } + DBG_871X_SEL_NL(m,"Peer Addr: "MAC_FMT"\n", MAC_ARG(peerinfo.wowlan_peer_addr)); + DBG_871X_SEL_NL(m,"Peer WPS Config: %x\n", peerinfo.wowlan_peer_wpsconfig); + DBG_871X_SEL_NL(m,"Persistent Group: %d\n", peerinfo.wowlan_peer_is_persistent); + DBG_871X_SEL_NL(m,"Intivation Type: %d\n", peerinfo.wowlan_peer_invitation_type); + } + else + { + DBG_871X_SEL_NL(m,"is_trigger: False\n"); + } + return 0; +} +#endif /* CONFIG_P2P_WOWLAN */ + +int proc_get_new_bcn_max(struct seq_file *m, void *v) +{ + extern int new_bcn_max; + + DBG_871X_SEL_NL(m, "%d", new_bcn_max); + return 0; +} + +ssize_t proc_set_new_bcn_max(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + char tmp[32]; + extern int new_bcn_max; + + if(count < 1) + return -EFAULT; + + if(buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + sscanf(tmp, "%d ", &new_bcn_max); + + return count; +} #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ieee80211.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ieee80211.c index 036b96bd0cfb..eabc91f58e16 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ieee80211.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_ieee80211.c @@ -19,6 +19,9 @@ ******************************************************************************/ #define _IEEE80211_C +#ifdef CONFIG_PLATFORM_INTEL_BYT +#include +#endif #include @@ -150,7 +153,6 @@ u8 *rtw_set_ie uint *frlen //frame length ) { -_func_enter_; *pbuf = (u8)index; *(pbuf + 1) = (u8)len; @@ -161,7 +163,6 @@ _func_enter_; *frlen = *frlen + (len + 2); return (pbuf + len + 2); -_func_exit_; } inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, @@ -1112,7 +1113,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, elems->wme_tspec_len = elen; break; default: - DBG_871X("unknown WME " + DBG_871X_LEVEL(_drv_warning_, "unknown WME " "information element ignored " "(subtype=%d len=%lu)\n", pos[4], (unsigned long) elen); @@ -1125,7 +1126,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, elems->wps_ie_len = elen; break; default: - DBG_871X("Unknown Microsoft " + DBG_871X_LEVEL(_drv_warning_, "Unknown Microsoft " "information element ignored " "(type=%d len=%lu)\n", pos[3], (unsigned long) elen); @@ -1140,7 +1141,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, elems->vendor_ht_cap_len = elen; break; default: - DBG_871X("Unknown Broadcom " + DBG_871X_LEVEL(_drv_warning_, "Unknown Broadcom " "information element ignored " "(type=%d len=%lu)\n", pos[3], (unsigned long) elen); @@ -1149,7 +1150,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, break; default: - DBG_871X("unknown vendor specific information " + DBG_871X_LEVEL(_drv_warning_, "unknown vendor specific information " "element ignored (vendor OUI %02x:%02x:%02x " "len=%lu)\n", pos[0], pos[1], pos[2], (unsigned long) elen); @@ -1290,9 +1291,10 @@ ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len, unknown++; if (!show_errors) break; - DBG_871X("IEEE 802.11 element parse " - "ignored unknown element (id=%d elen=%d)\n", - id, elen); + DBG_871X_LEVEL(_drv_warning_, + "IEEE 802.11 element parse " + "ignored unknown element (id=%d elen=%d)\n", + id, elen); break; } @@ -1347,8 +1349,40 @@ u8 convert_ip_addr(u8 hch, u8 mch, u8 lch) return ((key_char2num(hch) * 100) + (key_char2num(mch) * 10 ) + key_char2num(lch)); } +#ifdef CONFIG_PLATFORM_INTEL_BYT +#define MAC_ADDRESS_LEN 12 + +int rtw_get_mac_addr_intel(unsigned char *buf) +{ + int ret = 0; + int i; + struct file *fp = NULL; + mm_segment_t oldfs; + unsigned char c_mac[MAC_ADDRESS_LEN]; + char fname[]="/config/wifi/mac.txt"; + int jj,kk; + + DBG_871X("%s Enter\n", __FUNCTION__); + + ret = rtw_retrive_from_file(fname, c_mac, MAC_ADDRESS_LEN); + if(ret < MAC_ADDRESS_LEN) + { + return -1; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 2 ) + { + buf[jj] = key_2char2num(c_mac[kk], c_mac[kk+ 1]); + } + + DBG_871X("%s: read from file mac address: "MAC_FMT"\n", + __FUNCTION__, MAC_ARG(buf)); + + return 0; +} +#endif //CONFIG_PLATFORM_INTEL_BYT + extern char* rtw_initmac; -extern int rockchip_wifi_mac_addr(unsigned char *buf); void rtw_macaddr_cfg(u8 *mac_addr) { u8 mac[ETH_ALEN]; @@ -1364,17 +1398,15 @@ void rtw_macaddr_cfg(u8 *mac_addr) } _rtw_memcpy(mac_addr, mac, ETH_ALEN); } - else +#ifdef CONFIG_PLATFORM_INTEL_BYT + else if (0 == rtw_get_mac_addr_intel(mac)) { - printk("Wifi Efuse Mac => %02x:%02x:%02x:%02x:%02x:%02x\n", - mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); - if (!rockchip_wifi_mac_addr(mac_addr)) { - printk("Use flash MAC = %02x:%02x:%02x:%02x:%02x:%02x\n", - mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); - } else { - // Use the mac address stored in the Efuse - _rtw_memcpy(mac, mac_addr, ETH_ALEN); - } + _rtw_memcpy(mac_addr, mac, ETH_ALEN); + } +#endif //CONFIG_PLATFORM_INTEL_BYT + else + { // Use the mac address stored in the Efuse + _rtw_memcpy(mac, mac_addr, ETH_ALEN); } if (((mac[0]==0xff) &&(mac[1]==0xff) && (mac[2]==0xff) && @@ -1396,21 +1428,56 @@ void rtw_macaddr_cfg(u8 *mac_addr) DBG_871X("rtw_macaddr_cfg MAC Address = "MAC_FMT"\n", MAC_ARG(mac_addr)); } -void dump_ies(u8 *buf, u32 buf_len) +#ifdef CONFIG_80211N_HT +void dump_ht_cap_ie_content(void *sel, u8 *buf, u32 buf_len) +{ + if (buf_len != 26) { + DBG_871X_SEL_NL(sel, "Invalid HT capability IE len:%d != %d\n", buf_len, 26); + return; + } + + DBG_871X_SEL_NL(sel, "HT Capabilities Info:%02x%02x\n", *(buf), *(buf+1)); + DBG_871X_SEL_NL(sel, "A-MPDU Parameters:"HT_AMPDU_PARA_FMT"\n" + , HT_AMPDU_PARA_ARG(HT_CAP_ELE_AMPDU_PARA(buf))); + DBG_871X_SEL_NL(sel, "Supported MCS Set:"HT_SUP_MCS_SET_FMT"\n" + , HT_SUP_MCS_SET_ARG(HT_CAP_ELE_SUP_MCS_SET(buf))); +} + +void dump_ht_cap_ie(void *sel, u8 *ie, u32 ie_len) +{ + u8* pos = (u8*)ie; + u16 id; + u16 len; + + u8 *ht_cap_ie; + sint ht_cap_ielen; + + ht_cap_ie = rtw_get_ie(ie, _HT_CAPABILITY_IE_, &ht_cap_ielen, ie_len); + if(!ie || ht_cap_ie != ie) + return; + + dump_ht_cap_ie_content(sel, ht_cap_ie+2, ht_cap_ielen); +} +#endif /* CONFIG_80211N_HT */ + +void dump_ies(void *sel, u8 *buf, u32 buf_len) { u8* pos = (u8*)buf; u8 id, len; - while(pos-buf<=buf_len){ + while(pos-buf+10) - // dump_ies(ie, ielen); + // dump_ies(RTW_DBGDUMP, ie, ielen); break; } } @@ -1772,12 +1839,11 @@ void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) if( (p2p_ie=rtw_get_p2p_ie(bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_, NULL, &p2p_ielen_ori)) ) { - #if 0 + if (0) if(rtw_get_p2p_attr(p2p_ie, p2p_ielen_ori, attr_id, NULL, NULL)) { DBG_871X("rtw_get_p2p_attr: GOT P2P_ATTR:%u!!!!!!!!\n", attr_id); - dump_ies(bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_); + dump_ies(RTW_DBGDUMP, bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_); } - #endif p2p_ielen=rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id); if(p2p_ielen != p2p_ielen_ori) { @@ -1790,10 +1856,10 @@ void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) _rtw_memset(next_ie+remain_len, 0, p2p_ielen_ori-p2p_ielen); bss_ex->IELength -= p2p_ielen_ori-p2p_ielen; - #if 0 - DBG_871X("remove P2P_ATTR:%u!\n", attr_id); - dump_ies(bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_); - #endif + if (0) { + DBG_871X("remove P2P_ATTR:%u!\n", attr_id); + dump_ies(RTW_DBGDUMP, bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_); + } } } } @@ -1801,7 +1867,7 @@ void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) #endif //CONFIG_P2P #ifdef CONFIG_WFD -void dump_wfd_ie(u8 *ie, u32 ie_len) +void dump_wfd_ie(void *sel, u8 *ie, u32 ie_len) { u8* pos = (u8*)ie; u8 id; @@ -1818,7 +1884,7 @@ void dump_wfd_ie(u8 *ie, u32 ie_len) id = *pos; len = RTW_GET_BE16(pos+1); - DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); + DBG_871X_SEL_NL(sel, "%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); pos+=(3+len); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_iol.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_iol.c index 45dc60d0bebe..3524e1c5a5ed 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_iol.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_iol.c @@ -50,7 +50,7 @@ struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter) pattrib = &xmit_frame->attrib; update_mgntframe_attrib(adapter, pattrib); - pattrib->qsel = 0x10;//Beacon + pattrib->qsel = QSLT_BEACON;//Beacon pattrib->subtype = WIFI_BEACON; pattrib->pktlen = pattrib->last_txcmdsz = 0; @@ -62,7 +62,7 @@ struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter) else { pattrib = &xmit_frame->attrib; update_mgntframe_attrib(adapter, pattrib); - pattrib->qsel = 0x10; + pattrib->qsel = QSLT_BEACON; pattrib->pktlen = pattrib->last_txcmdsz = 0; } #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme.c index df6dfc85ccdc..1047bc0269be 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme.c @@ -155,7 +155,10 @@ void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) void _rtw_free_mlme_priv (struct mlme_priv *pmlmepriv) { _func_enter_; - + if (NULL == pmlmepriv){ + rtw_warn_on(1); + goto exit; + } rtw_free_mlme_priv_ie_data(pmlmepriv); if(pmlmepriv){ @@ -165,6 +168,7 @@ _func_enter_; rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network)); } } +exit: _func_exit_; } @@ -863,7 +867,9 @@ void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target) ULONG bssid_ex_sz; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); - struct wifidirect_info *pwdinfo= &(adapter->wdinfo); +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(adapter->wdinfo); +#endif // CONFIG_P2P _queue *queue = &(pmlmepriv->scanned_queue); struct wlan_network *pnetwork = NULL; struct wlan_network *oldest = NULL; @@ -891,7 +897,7 @@ _func_enter_; rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork); #ifdef CONFIG_P2P - if (!rtw_p2p_chk_state(&(adapter->wdinfo), P2P_STATE_NONE) && + if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && (_rtw_memcmp(pnetwork->network.MacAddress, target->MacAddress, ETH_ALEN) == _TRUE)) { target_find = 1; @@ -1489,16 +1495,16 @@ _func_enter_; rtw_tdls_cmd(adapter, myid(&(adapter->eeprompriv)), TDLS_RS_RCR); rtw_reset_tdls_info(adapter); rtw_free_all_stainfo(adapter); - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); } else #endif //CONFIG_TDLS { - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(adapter, psta); } - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); } @@ -1509,9 +1515,9 @@ _func_enter_; rtw_free_all_stainfo(adapter); psta = rtw_get_bcmc_stainfo(adapter); - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(adapter, psta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_init_bcmc_stainfo(adapter); } @@ -1519,36 +1525,19 @@ _func_enter_; if(lock_scanned_queue) _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); - pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); +// pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); + pwlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, tgt_network); if(pwlan) { pwlan->fixed = _FALSE; + + DBG_871X("free disconnecting network\n"); + rtw_free_network_nolock(adapter, pwlan); #ifdef CONFIG_P2P if(!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) { - u32 p2p_ielen=0; - u8 *p2p_ie; - //u16 capability; - u8 *pcap = NULL; - u32 capability_len=0; - - //DBG_871X("free disconnecting network\n"); - //rtw_free_network_nolock(pmlmepriv, pwlan); - - if((p2p_ie=rtw_get_p2p_ie(pwlan->network.IEs+_FIXED_IE_LENGTH_, pwlan->network.IELength-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))) - { - pcap = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, NULL, &capability_len); - if(pcap && capability_len==2) - { - u16 cap = *(u16*)pcap ; - *(u16*)pcap = cap&0x00ff;//clear group capability when free this network - } - - } - rtw_set_scan_deny(adapter, 2000); - //rtw_clear_scan_deny(adapter); - + //rtw_clear_scan_deny(adapter); } #endif //CONFIG_P2P } @@ -1644,6 +1633,8 @@ void rtw_indicate_disconnect( _adapter *padapter ) WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; + u8 *wps_ie=NULL; + uint wpsie_len=0; _func_enter_; @@ -1651,6 +1642,22 @@ _func_enter_; _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS); + // force to clear cur_network_scanned's SELECTED REGISTRAR + if (pmlmepriv->cur_network_scanned) { + WLAN_BSSID_EX *current_joined_bss = &(pmlmepriv->cur_network_scanned->network); + if (current_joined_bss) { + wps_ie=rtw_get_wps_ie(current_joined_bss->IEs +_FIXED_IE_LENGTH_, + current_joined_bss->IELength-_FIXED_IE_LENGTH_, NULL, &wpsie_len); + if (wps_ie && wpsie_len>0) { + u8 *attr = NULL; + u32 attr_len; + attr=rtw_get_wps_attr(wps_ie, wpsie_len, WPS_ATTR_SELECTED_REGISTRAR, + NULL, &attr_len); + if (attr) + *(attr + 4) = 0; + } + } + } //DBG_871X("clear wps when %s\n", __func__); if(rtw_to_roam(padapter) > 0) @@ -1724,17 +1731,17 @@ inline void rtw_indicate_scan_done( _adapter *padapter, bool aborted) #endif // CONFIG_IPS } -void rtw_scan_abort(_adapter *adapter) +u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms) { - u32 cnt=0; u32 start; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + u32 pass_ms; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); start = rtw_get_current_time(); pmlmeext->scan_abort = _TRUE; while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) - && rtw_get_passing_time_ms(start) <= 200) { + && rtw_get_passing_time_ms(start) <= timeout_ms) { if (adapter->bDriverStopped || adapter->bSurpriseRemoved) break; @@ -1749,11 +1756,28 @@ void rtw_scan_abort(_adapter *adapter) #ifdef CONFIG_PLATFORM_MSTAR //_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); set_survey_timer(pmlmeext, 0); - _set_timer(&pmlmepriv->scan_to_timer, 50); + mlme_set_scan_to_timer(pmlmepriv, 50); #endif rtw_indicate_scan_done(adapter, _TRUE); } pmlmeext->scan_abort = _FALSE; + pass_ms = rtw_get_passing_time_ms(start); + + return pass_ms; +} + +void rtw_scan_abort_no_wait(_adapter *adapter) +{ + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + pmlmeext->scan_abort = _TRUE; +} + +void rtw_scan_abort(_adapter *adapter) +{ + rtw_scan_abort_timeout(adapter, 200); } static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork) @@ -2039,9 +2063,9 @@ _func_enter_; pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); if(pcur_sta){ - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); rtw_free_stainfo(adapter, pcur_sta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); } ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); @@ -2487,6 +2511,7 @@ _func_enter_; rtw_free_assoc_resources(adapter, 1); rtw_indicate_disconnect(adapter); + rtw_free_mlme_priv_ie_data(pmlmepriv); _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); // remove the network entry in scanned_queue @@ -2509,9 +2534,9 @@ _func_enter_; check_fwstate(pmlmepriv,WIFI_ADHOC_STATE)) { - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(adapter, psta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); if(adapter->stapriv.asoc_sta_count== 1) //a sta + bc/mc_stainfo (not Ibss_stainfo) { @@ -2838,7 +2863,7 @@ void rtw_dynamic_check_timer_handlder(_adapter *adapter) { u8 bEnterPS; - linked_status_chk(adapter); + linked_status_chk(adapter, 1); bEnterPS = traffic_status_watchdog(adapter, 1); if(bEnterPS) @@ -3506,22 +3531,67 @@ static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid) // 13th element in the array is the IE length // -static int rtw_append_pmkid(_adapter *Adapter,int iEntry, u8 *ie, uint ie_len) +static int rtw_append_pmkid(_adapter *adapter,int iEntry, u8 *ie, uint ie_len) { - struct security_priv *psecuritypriv=&Adapter->securitypriv; + struct security_priv *sec=&adapter->securitypriv; - if(ie[13]<=20){ - // The RSN IE didn't include the PMK ID, append the PMK information - ie[ie_len]=1; - ie_len++; - ie[ie_len]=0; //PMKID count = 0x0100 - ie_len++; - _rtw_memcpy( &ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16); - - ie_len+=16; - ie[13]+=18;//PMKID length = 2+16 + if (ie[13] > 20) { + int i; + u16 pmkid_cnt = RTW_GET_LE16(ie+14+20); + if (pmkid_cnt == 1 && _rtw_memcmp(ie+14+20+2, &sec->PMKIDList[iEntry].PMKID, 16)) { + DBG_871X(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n" + , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[iEntry].PMKID)); + goto exit; + } + + DBG_871X(FUNC_ADPT_FMT" remove original PMKID, count:%u\n" + , FUNC_ADPT_ARG(adapter), pmkid_cnt); + + for (i=0;iPMKIDList[iEntry].PMKID)); + + RTW_PUT_LE16(&ie[ie_len], 1); + ie_len += 2; + + _rtw_memcpy(&ie[ie_len], &sec->PMKIDList[iEntry].PMKID, 16); + ie_len += 16; + + ie[13] += 18;//PMKID length = 2+16 } + +exit: + return (ie_len); +} + +static int rtw_remove_pmkid(_adapter *adapter, u8 *ie, uint ie_len) +{ + struct security_priv *sec=&adapter->securitypriv; + int i; + u16 pmkid_cnt = RTW_GET_LE16(ie+14+20); + + if (ie[13] <= 20) + goto exit; + + DBG_871X(FUNC_ADPT_FMT" remove original PMKID, count:%u\n" + , FUNC_ADPT_ARG(adapter), pmkid_cnt); + + for (i=0;iassoc_bssid); if(iEntry<0) { - return ielength; + if(authmode == _WPA2_IE_ID_) + ielength = rtw_remove_pmkid(adapter, out_ie, ielength); } else { if(authmode == _WPA2_IE_ID_) - { ielength=rtw_append_pmkid(adapter, iEntry, out_ie, ielength); - } } _func_exit_; @@ -3712,17 +3781,10 @@ void rtw_joinbss_reset(_adapter *padapter) { u8 threshold; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - -#ifdef CONFIG_80211N_HT - struct ht_priv *phtpriv = &pmlmepriv->htpriv; -#endif - //todo: if you want to do something io/reg/hw setting before join_bss, please add code here - - - -#ifdef CONFIG_80211N_HT +#ifdef CONFIG_80211N_HT + struct ht_priv *phtpriv = &pmlmepriv->htpriv; pmlmepriv->num_FortyMHzIntolerant = 0; @@ -3746,9 +3808,9 @@ void rtw_joinbss_reset(_adapter *padapter) threshold = 1; rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); } -#endif +#endif//#if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) -#endif +#endif//#ifdef CONFIG_80211N_HT } @@ -3985,11 +4047,17 @@ unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, ui //rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03); - if(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ ) - ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2)); + if(padapter->driver_rx_ampdu_spacing != 0xFF) + { + ht_capie.ampdu_params_info |= (( padapter->driver_rx_ampdu_spacing&0x07) <<2); + } else - ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00); - + { + if(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ ) + ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2)); + else + ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00); + } #ifdef CONFIG_BEAMFORMING ht_capie.tx_BF_cap_info = 0; @@ -4484,3 +4552,18 @@ u8 rtw_get_buddy_bBusyTraffic(_adapter *padapter) } #endif //CONFIG_CONCURRENT_MODE + +static const char *miracast_mode_str[] = { + "DISABLED", + "SOURCE", + "SINK", + "INVALID", +}; + +const char *get_miracast_mode_str(int mode) +{ + if (mode < MIRACAST_DISABLED || mode >= MIRACAST_INVALID) + mode = MIRACAST_INVALID; + + return miracast_mode_str[mode]; +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme_ext.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme_ext.c index 4f50cb794295..7cf52d00d135 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme_ext.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mlme_ext.c @@ -171,7 +171,7 @@ static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = { {{56,60,64,149,153,157,161,165},8}, // 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 {{149,153,157,161,165},5}, // 0x11, RT_CHANNEL_DOMAIN_5G_NCC3 {{36,40,44,48},4}, // 0x12, RT_CHANNEL_DOMAIN_5G_ETSI4 - {{36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},20}, // 0x13, RT_CHANNEL_DOMAIN_5G_ETSI5 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x13, RT_CHANNEL_DOMAIN_5G_ETSI5 {{149,153,157,161},4}, // 0x14, RT_CHANNEL_DOMAIN_5G_FCC8 {{36,40,44,48,52,56,60,64},8}, // 0x15, RT_CHANNEL_DOMAIN_5G_ETSI6 {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, // 0x16, RT_CHANNEL_DOMAIN_5G_ETSI7 @@ -181,14 +181,17 @@ static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = { {{36,40,44,48,52,56,60,64,132,136,140,149,153,157,161,165},16}, // 0x1A, RT_CHANNEL_DOMAIN_5G_ETSI11 {{52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},17}, // 0x1B, RT_CHANNEL_DOMAIN_5G_NCC4 {{149,153,157,161},4}, // 0x1C, RT_CHANNEL_DOMAIN_5G_ETSI12 - {{36,40,44,48,100,104,108,112,116,132,136,140,149,153,157,161,165},17}, // 0x1D, RT_CHANNEL_DOMAIN_5G_FCC9 - {{36,40,44,48,100,104,108,112,116,132,136,140},12}, // 0x1E, RT_CHANNEL_DOMAIN_5G_ETSI13 - {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161},20}, // 0x1F, RT_CHANNEL_DOMAIN_5G_FCC10 - + {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x1D, RT_CHANNEL_DOMAIN_5G_FCC9 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140},16}, // 0x1E, RT_CHANNEL_DOMAIN_5G_ETSI13 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161},20}, // 0x1F, RT_CHANNEL_DOMAIN_5G_FCC10 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161},19}, // 0x20, RT_CHANNEL_DOMAIN_5G_KCC2 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x21, RT_CHANNEL_DOMAIN_5G_FCC11 + {{56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},16}, // 0x22, RT_CHANNEL_DOMAIN_5G_NCC5 + {{36,40,44,48},4}, // 0x23, RT_CHANNEL_DOMAIN_5G_MKK4 //===== Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition ===== - {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x20, RT_CHANNEL_DOMAIN_5G_FCC - {{36,40,44,48},4}, // 0x21, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS - {{36,40,44,48,149,153,157,161},8}, // 0x22, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS + {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x30, RT_CHANNEL_DOMAIN_5G_FCC + {{36,40,44,48},4}, // 0x31, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS + {{36,40,44,48,149,153,157,161},8}, // 0x32, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS }; static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { @@ -234,7 +237,7 @@ static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { {0x02,0x04}, //0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 {0x00,0x01}, //0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 {0x03,0x0C}, //0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 - {0x00,0x0B}, //0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 + {0x00,0x20}, //0x28, RT_CHANNEL_DOMAIN_5G_KCC2 {0x00,0x05}, //0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 {0x00,0x00}, //0x2A, {0x00,0x00}, //0x2B, @@ -246,12 +249,12 @@ static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { {0x00,0x07}, //0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 {0x00,0x08}, //0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 {0x00,0x09}, //0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 - {0x02,0x0A}, //0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 + {0x02,0x21}, //0x34, RT_CHANNEL_DOMAIN_5G_FCC11 {0x00,0x02}, //0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 {0x00,0x03}, //0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 {0x03,0x0D}, //0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 {0x03,0x0E}, //0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 - {0x02,0x0F}, //0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 + {0x02,0x22}, //0x39, RT_CHANNEL_DOMAIN_5G_NCC5 {0x00,0x00}, //0x3A, {0x00,0x00}, //0x3B, {0x00,0x00}, //0x3C, @@ -268,6 +271,12 @@ static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { {0x00,0x15}, //0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 {0x00,0x16}, //0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 {0x00,0x17}, //0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 + {0x00,0x00}, //0x4A, + {0x00,0x00}, //0x4B, + {0x00,0x00}, //0x4C, + {0x00,0x00}, //0x4D, + {0x00,0x00}, //0x4E, + {0x00,0x00}, //0x4F, {0x00,0x18}, //0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 {0x00,0x19}, //0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 {0x00,0x1A}, //0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 @@ -276,9 +285,10 @@ static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { {0x02,0x1D}, //0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 {0x00,0x1E}, //0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 {0x02,0x1F}, //0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 + {0x01,0x23}, //0x58, RT_CHANNEL_DOMAIN_WORLD_MKK4 }; -static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03,0x02}; //use the conbination for max channel numbers +static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x01,0x02}; //use the conbination for max channel numbers /* * Search the @param ch in given @param ch_set @@ -341,7 +351,7 @@ void init_mlme_default_rate_set(_adapter* padapter) unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,_9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff}; unsigned char mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,}; - unsigned char supported_mcs_set[16] = {0xff, 0xff, 0x00, 0x00, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + unsigned char supported_mcs_set[16] = {0xff, 0xff, 0x00, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates); _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates); @@ -912,12 +922,13 @@ unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame) // Commented by Kurt 2012/10/16 // IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client -#ifdef CONFIG_WIFI_TEST - if ( pattrib->data_rate <= 3 ) - { - wifi_test_chk_rate = 0; - } -#endif //CONFIG_WIFI_TEST + if (padapter->registrypriv.wifi_spec == 1) + { + if ( pattrib->data_rate <= 3 ) + { + wifi_test_chk_rate = 0; + } + } if( wifi_test_chk_rate == 1 ) { @@ -1284,8 +1295,23 @@ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX)); if (pbss) { if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { + struct beacon_keys recv_beacon; + update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE); rtw_get_bcn_info(&(pmlmepriv->cur_network)); + + // update bcn keys + if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) { + DBG_871X("%s: beacon keys ready\n", __func__); + _rtw_memcpy(&pmlmepriv->cur_beacon_keys, + &recv_beacon, sizeof(recv_beacon)); + pmlmepriv->new_beacon_cnts = 0; + } + else { + DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__); + _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon)); + pmlmepriv->new_beacon_cnts = 0; + } } rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX)); } @@ -6535,14 +6561,14 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) { u8 wireless_mode; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); pattrib->hdrlen = 24; pattrib->nr_frags = 1; pattrib->priority = 7; pattrib->mac_id = 0; - pattrib->qsel = 0x12; + pattrib->qsel = QSLT_MGNT; pattrib->pktlen = 0; @@ -6567,6 +6593,7 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) pattrib->retry_ctrl = _TRUE; pattrib->mbssid = 0; + pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no; } @@ -6742,7 +6769,7 @@ void issue_beacon(_adapter *padapter, int timeout_ms) //update attribute pattrib = &pmgntframe->attrib; update_mgntframe_attrib(padapter, pattrib); - pattrib->qsel = 0x10; + pattrib->qsel = QSLT_BEACON; #ifdef CONFIG_CONCURRENT_MODE if(padapter->iface_type == IFACE_PORT1) pattrib->mbssid = 1; @@ -8002,21 +8029,20 @@ void issue_assocreq(_adapter *padapter) #endif #endif // Check if the AP's supported rates are also supported by STA. - if (bssrate_len == 0) { + if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) { rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); rtw_free_xmitframe(pxmitpriv, pmgntframe); goto exit; //don't connect to AP if no joint supported rate } - if (bssrate_len > 8) - { + if (bssrate_len > 8) { pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen)); pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); - } - else - { + } else if (bssrate_len > 0) { pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } else { + DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n", __FUNCTION__); } //vendor specific IE, such as WPA, WMM, WPS @@ -8442,7 +8468,7 @@ exit: * The null data packet would be sent without power bit, * and not guarantee success. */ -s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da) +s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode) { int ret; struct mlme_ext_priv *pmlmeext; @@ -8456,7 +8482,7 @@ s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da) if (da == NULL) da = get_my_bssid(&(pmlmeinfo->network)); - ret = _issue_nulldata(padapter, da, 0, _FALSE); + ret = _issue_nulldata(padapter, da, power_mode, _FALSE); return ret; } @@ -8989,7 +9015,8 @@ void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char act if (padapter->fix_ba_rxbuf_bz != 0xFF) ba_rxbuf_sz = padapter->fix_ba_rxbuf_bz; - ba_rxbuf_sz &= 0x03ff; + if (ba_rxbuf_sz > 127) + ba_rxbuf_sz = 127; BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; BA_para_set |= (ba_rxbuf_sz << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; @@ -9186,6 +9213,140 @@ static void issue_action_BSSCoexistPacket(_adapter *padapter) #endif //CONFIG_80211N_HT } +// Spatial Multiplexing Powersave (SMPS) action frame +int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack) +{ + + int ret=0; + unsigned char category = RTW_WLAN_CATEGORY_HT; + u8 action = RTW_WLAN_ACTION_HT_SM_PS; + u8 sm_power_control=0; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + + if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED) + { + sm_power_control = sm_power_control & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable + } + else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC) + { + sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable + sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode + } + else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC) + { + sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable + sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode + } + else + return ret; + + DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode ); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return ret; + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */ + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */ + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */ + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + /* category, action */ + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen)); + + pattrib->last_txcmdsz = pattrib->pktlen; + + if(wait_ack) + { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } + else + { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + + if (ret != _SUCCESS) + DBG_8192C("%s, ack to\n", __func__); + + return ret; +} + +int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms) +{ + int ret = 0; + int i = 0; + u32 start = rtw_get_current_time(); + + do { + ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE ); + + i++; + + if (padapter->bDriverStopped || padapter->bSurpriseRemoved) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((istapriv; @@ -9257,13 +9418,16 @@ unsigned int send_beacon(_adapter *padapter) //#endif #ifdef CONFIG_PCI_HCI - //DBG_871X("%s\n", __FUNCTION__); + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); + + /* 8192EE Port select for Beacon DL */ + rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); + issue_beacon(padapter, 0); return _SUCCESS; - #endif #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -9423,18 +9587,26 @@ void site_survey(_adapter *padapter) //val8 |= 0x0f; //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH) - if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) - { - if( pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH ) - { - pmlmeinfo->scan_cnt = 0; - survey_channel = pbuddy_mlmeext->cur_channel; - stay_buddy_ch = 1; - } - else - { - if( pmlmeinfo->scan_cnt == 0 ) + if ((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) { + if (pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH) { + if (pmlmeinfo->backop_cnt == 0) + stay_buddy_ch = 1; + else if (pmlmeinfo->backop_cnt == RTW_STAY_AP_CH_MILLISECOND) stay_buddy_ch = 2; + + if (stay_buddy_ch == 2) { + pmlmeinfo->scan_cnt = 1; + pmlmeinfo->backop_cnt = 0; + } else if (stay_buddy_ch == 1) { + pmlmeinfo->backop_cnt++; + survey_channel = pbuddy_mlmeext->cur_channel; + } else { + pmlmeinfo->backop_cnt++; + set_survey_timer(pmlmeext, pmlmeext->chan_scan_time); + return; + } + } else { + pmlmeinfo->scan_cnt++; } } @@ -9520,22 +9692,12 @@ void site_survey(_adapter *padapter) // 1,2-6-3,4-6-5,6-6-7,8-6-9,10-6-11,12-6-13,14 //if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)==_TRUE) - if( stay_buddy_ch == 1 ){ - channel_scan_time_ms = pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND; - } - else { - if( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) - channel_scan_time_ms = 20; - else - channel_scan_time_ms = 40 - } -#elif defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) - if( stay_buddy_ch == 1 ) - channel_scan_time_ms = pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND ; - else - channel_scan_time_ms = pmlmeext->chan_scan_time; + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + channel_scan_time_ms = 20; + else + channel_scan_time_ms = 40; #else - channel_scan_time_ms = pmlmeext->chan_scan_time; + channel_scan_time_ms = pmlmeext->chan_scan_time; #endif set_survey_timer(pmlmeext, channel_scan_time_ms); @@ -9609,12 +9771,13 @@ void site_survey(_adapter *padapter) rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN); pmlmeext->sitesurvey_res.state = SCAN_DISABLE; - initialgain = 0xff; //restore RX GAIN - rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); - //turn on dynamic functions + //turn on phy-dynamic functions Restore_DM_Func_Flag(padapter); //Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); + initialgain = 0xff; //restore RX GAIN + rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + _set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) ); } else @@ -9623,6 +9786,7 @@ void site_survey(_adapter *padapter) #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH) pmlmeinfo->scan_cnt = 0; + pmlmeinfo->backop_cnt = 0; #endif #ifdef CONFIG_ANTENNA_DIVERSITY @@ -9689,11 +9853,13 @@ void site_survey(_adapter *padapter) //config MSR Set_MSR(padapter, (pmlmeinfo->state & 0x3)); - initialgain = 0xff; //restore RX GAIN - rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); - //turn on dynamic functions + //turn on phy-dynamic functions Restore_DM_Func_Flag(padapter); //Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); + + initialgain = 0xff; //restore RX GAIN + rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + if (is_client_associated_to_ap(padapter) == _TRUE) { @@ -10074,6 +10240,7 @@ void start_clnt_join(_adapter* padapter) struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); int beacon_timeout; + u8 ASIX_ID[]= {0x00, 0x0E, 0xC6}; //update wireless mode update_wireless_mode(padapter); @@ -10081,6 +10248,12 @@ void start_clnt_join(_adapter* padapter) //udpate capability caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork); update_capinfo(padapter, caps); + + //check if sta is ASIX peer and fix IOT issue if it is. + if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) { + u8 iot_flag = _TRUE; + rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag)); + } if (caps&cap_ESS) { Set_MSR(padapter, WIFI_FW_STATION_STATE); @@ -11026,6 +11199,7 @@ static void rtw_mlmeext_disconnect(_adapter *padapter) struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); u8 state_backup = (pmlmeinfo->state&0x03); + u8 ASIX_ID[]= {0x00, 0x0E, 0xC6}; //set_opmode_cmd(padapter, infra_client_with_mlme); @@ -11051,6 +11225,11 @@ static void rtw_mlmeext_disconnect(_adapter *padapter) //set MSR to no link state -> infra. mode Set_MSR(padapter, _HW_STATE_STATION_); + //check if sta is ASIX peer and fix IOT issue if it is. + if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) { + u8 iot_flag = _FALSE; + rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag)); + } pmlmeinfo->state = WIFI_FW_NULL_STATE; if(state_backup == WIFI_FW_STATION_STATE) @@ -11305,10 +11484,10 @@ void _linked_info_dump(_adapter *padapter) { int i; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 mac_id; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); int UndecoratedSmoothedPWDB; - struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); if(padapter->bLinkInfoDump){ @@ -11343,13 +11522,13 @@ void _linked_info_dump(_adapter *padapter) _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); } - for(i=0; inum; i++) { - if(pdvobj->macid[i] == _TRUE) - { - if(i !=1) //skip bc/mc sta - //============ tx info ============ - rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i); + if(rtw_macid_is_used(macid_ctl, i) + && !rtw_macid_is_bmc(macid_ctl, i) /* skip bc/mc sta */ + ) { + //============ tx info ============ + rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i); } } rtw_hal_set_def_var(padapter, HAL_DEF_DBG_RX_INFO_DUMP, NULL); @@ -11513,7 +11692,8 @@ struct candidate_pool{ } #endif //CONFIG_TDLS -void linked_status_chk(_adapter *padapter) +//from_timer == 1 means driver is in LPS +void linked_status_chk(_adapter *padapter, u8 from_timer) { u32 i; struct sta_info *psta; @@ -11540,10 +11720,20 @@ void linked_status_chk(_adapter *padapter) #endif #ifdef CONFIG_P2P if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) - link_count_limit = 3; // 8 sec + { + if(!from_timer) + link_count_limit = 3; // 8 sec + else + link_count_limit = 15; // 32 sec + } else #endif // CONFIG_P2P - link_count_limit = 7; // 16 sec + { + if(!from_timer) + link_count_limit = 7; // 16 sec + else + link_count_limit = 29; // 60 sec + } // Marked by Kurt 20130715 // For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. @@ -11607,9 +11797,9 @@ void linked_status_chk(_adapter *padapter) if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) { #ifdef DBG_EXPIRATION_CHK - DBG_871X("%s issue_nulldata 0\n", __FUNCTION__); + DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0); #endif - tx_chk = issue_nulldata_in_interrupt(padapter, NULL); + tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0); } } @@ -11700,7 +11890,8 @@ void survey_timer_hdl(_adapter *padapter) if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH) - if( padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH ) + if (padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH + || padapter->mlmeextpriv.mlmext_info.backop_cnt == RTW_STAY_AP_CH_MILLISECOND) #endif pmlmeext->sitesurvey_res.channel_idx++; } @@ -11833,7 +12024,7 @@ void link_timer_hdl(_adapter *padapter) { if (tx_cnt == pxmitpriv->tx_pkts) { - issue_nulldata_in_interrupt(padapter, NULL); + issue_nulldata_in_interrupt(padapter, NULL, 0); } tx_cnt = pxmitpriv->tx_pkts; @@ -12124,14 +12315,14 @@ u8 createbss_hdl(_adapter *padapter, u8 *pbuf) pmlmeinfo->agg_enable_bitmap = 0; pmlmeinfo->candidate_tid_bitmap = 0; - //disable dynamic functions, such as high power, DIG - Save_DM_Func_Flag(padapter); - Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); - //config the initial gain under linking, need to write the BB registers //initialgain = 0x1E; //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + //disable dynamic functions, such as high power, DIG + Save_DM_Func_Flag(padapter); + Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); + //cancel link timer _cancel_timer_ex(&pmlmeext->link_timer); @@ -12418,8 +12609,107 @@ u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf) return H2C_SUCCESS; } -int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out, - u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num) +u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num) +{ +/* interval larger than this is treated as backgroud scan */ +#ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS +#define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000 +#endif + +#ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST +#define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1 +#endif +#ifndef RTW_SCAN_SPARSE_CH_NUM_BG +#define RTW_SCAN_SPARSE_CH_NUM_BG 4 +#endif + +#define SCAN_SPARSE_CH_NUM_INVALID 255 + + static u8 token = 255; + u32 interval; + bool busy_traffic = _FALSE; + bool miracast_enabled = _FALSE; + bool bg_scan = _FALSE; + u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID; + u8 scan_division_num; + u8 ret_num = ch_num; + struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter)); + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + + if (regsty->wifi_spec) + goto exit; + + /* assume ch_num > 6 is normal scan */ + if (ch_num <= 6) + goto exit; + + if (mlmeext->last_scan_time == 0) + mlmeext->last_scan_time = rtw_get_current_time(); + + interval = rtw_get_passing_time_ms(mlmeext->last_scan_time); + + if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE + #ifdef CONFIG_CONCURRENT_MODE + || (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) + #endif + ) + busy_traffic = _TRUE; + + #ifdef CONFIG_WFD + if (is_miracast_enabled(adapter->wfd_info.stack_wfd_mode) + #ifdef CONFIG_CONCURRENT_MODE + || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter->wfd_info.stack_wfd_mode)) + #endif + ) + miracast_enabled = _TRUE; + #endif + + if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS) + bg_scan = _TRUE; + + /* max_allow_ch by conditions*/ + + #if RTW_SCAN_SPARSE_MIRACAST + if (miracast_enabled == _TRUE && busy_traffic == _TRUE) + max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST); + #endif + + #if RTW_SCAN_SPARSE_BG + if (bg_scan == _TRUE) + max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG); + #endif + + + if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) { + int i; + int k = 0; + + scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0); + token = (token + 1) % scan_division_num; + + if (0) + DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token); + + for (i = 0; i < ch_num; i++) { + if (ch[i].hw_value && (i % scan_division_num) == token + ) { + if (i != k) + _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel)); + k++; + } + } + + _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel)); + + ret_num = k; + mlmeext->last_scan_time = rtw_get_current_time(); + } + +exit: + return ret_num; +} + +static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out, u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num) { int i, j; int scan_ch_num = 0; @@ -12483,49 +12773,8 @@ int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out, } } -#ifdef CONFIG_SCAN_SPARSE //partial scan, ASUS RK3188 use the feature - /* assume j>6 is normal scan */ - if ((j > 6) && (padapter->registrypriv.wifi_spec != 1)) - { - static u8 token = 0; - u32 interval; - - if (pmlmeext->last_scan_time == 0) - pmlmeext->last_scan_time = rtw_get_current_time(); - - interval = rtw_get_passing_time_ms(pmlmeext->last_scan_time); - if ((interval > ALLOW_SCAN_INTERVAL) -#if 0 // Miracast can't do AP scan - || (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) -#ifdef CONFIG_CONCURRENT_MODE - || (padapter->pbuddy_adapter - && (padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)) -#endif // CONFIG_CONCURRENT_MODE -#endif - ) - { - // modify scan plan - int k = 0; - _rtw_memset(in, 0, sizeof(struct rtw_ieee80211_channel)*in_num); - _rtw_memcpy(in, out, sizeof(struct rtw_ieee80211_channel)*j); - _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*j); - - for (i=0;i=out_num) - break; - } - - j = k; - token = (token+1)%SCAN_DIVISION_NUM; - } - - pmlmeext->last_scan_time = rtw_get_current_time(); - } -#endif //CONFIG_SCAN_SPARSE + /* scan_sparse */ + j = rtw_scan_sparse(padapter, out, j); return j; } @@ -12635,10 +12884,6 @@ u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf) #endif #endif /* CONFIG_FIND_BEST_CHANNEL */ - //disable dynamic functions, such as high power, DIG - Save_DM_Func_Flag(padapter); - Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); - //config the initial gain under scaning, need to write the BB registers #ifdef CONFIG_P2P #ifdef CONFIG_IOCTL_CFG80211 @@ -12653,6 +12898,10 @@ u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf) initialgain = 0x1e; rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + + //disable dynamic functions, such as high power, DIG + Save_DM_Func_Flag(padapter); + Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); //set MSR to no link state Set_MSR(padapter, _HW_STATE_NOLINK_); @@ -13002,7 +13251,7 @@ u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf) pxmitframe->attrib.triggered=1; if (xmitframe_hiq_filter(pxmitframe) == _TRUE) - pxmitframe->attrib.qsel = 0x11;//HIQ + pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ #if 0 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); @@ -14219,12 +14468,10 @@ u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set); init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); + rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE); + #ifdef CONFIG_IOCTL_CFG80211 - if ((padapter->rtw_wdev != NULL) && (padapter->rtw_wdev->wiphy)) { - struct regulatory_request request; - request.initiator = NL80211_REGDOM_SET_BY_DRIVER; - rtw_reg_notifier(padapter->rtw_wdev->wiphy, &request); - } + rtw_reg_notify_by_driver(padapter); #endif //CONFIG_IOCTL_CFG80211 return H2C_SUCCESS; @@ -14490,3 +14737,18 @@ u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf) } +u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf) +{ + struct RunInThread_param *p; + + + if (NULL == pbuf) + return H2C_PARAMETERS_ERROR; + p = (struct RunInThread_param*)pbuf; + + if (p->func) + p->func(p->context); + + return H2C_SUCCESS; +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp.c index 3db2a2c8bfce..772633e1111e 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp.c @@ -25,7 +25,7 @@ #include /* for RFHIGHPID */ #endif -#include "../hal/OUTSRC/odm_precomp.h" +#include "../hal/OUTSRC/phydm_precomp.h" #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8821A) #include #endif @@ -292,7 +292,7 @@ s32 init_mp_priv(PADAPTER padapter) pmppriv->tx.stop = 1; pmppriv->bSetTxPower=0; //for manually set tx power pmppriv->bTxBufCkFail=_FALSE; - pmppriv->pktInterval=1; + pmppriv->pktInterval=0; mp_init_xmit_attrib(&pmppriv->tx, padapter); @@ -423,7 +423,7 @@ void mpt_InitHWConfig(PADAPTER Adapter) #define PHY_IQCalibrate(_Adapter, b) \ IS_HARDWARE_TYPE_8812(_Adapter) ? PHY_IQCalibrate_8812A(_Adapter, b) : \ - IS_HARDWARE_TYPE_8821(_Adapter) ? PHY_IQCalibrate_8821A(_Adapter, b) : \ + IS_HARDWARE_TYPE_8821(_Adapter) ? PHY_IQCalibrate_8821A(&(GET_HAL_DATA(_Adapter)->odmpriv), b) : \ PHY_IQCalibrate_default(_Adapter, b) #define PHY_LCCalibrate(_Adapter) \ @@ -449,17 +449,13 @@ static void PHY_IQCalibrate(PADAPTER padapter, u8 bReCovery) u8 b2ant; //false:1ant, true:2-ant u8 RF_Path; //0:S1, 1:S0 - pHalData = GET_HAL_DATA(padapter); b2ant = pHalData->EEPROMBluetoothAntNum==Ant_x2?_TRUE:_FALSE; - RF_Path = 0; -#ifdef CONFIG_USB_HCI - RF_Path = 1; -#endif - PHY_IQCalibrate_8723B(padapter, bReCovery, _FALSE, b2ant, RF_Path); + PHY_IQCalibrate_8723B(padapter, bReCovery, _FALSE, b2ant, pHalData->ant_path); } + #define PHY_LCCalibrate(a) PHY_LCCalibrate_8723B(&(GET_HAL_DATA(a)->odmpriv)) #define PHY_SetRFPathSwitch(a,b) PHY_SetRFPathSwitch_8723B(a,b) #endif @@ -1269,7 +1265,7 @@ static thread_return mp_xmit_packet_thread(thread_context context) goto exit; } else { - rtw_usleep_os(100); + rtw_usleep_os(10); continue; } } @@ -1469,8 +1465,15 @@ void fill_tx_desc_8192e(PADAPTER padapter) offset = TXDESC_SIZE + OFFSET_SZ; + SET_TX_DESC_OFFSET_92E(pDesc, offset); + + #if defined(CONFIG_PCI_HCI) //8192EE + SET_TX_DESC_OFFSET_92E(pDesc, offset+8); //work around + SET_TX_DESC_PKT_OFFSET_92E(pDesc, 0); /* 8192EE pkt_offset is 0 */ + #else //8192EU 8192ES SET_TX_DESC_OFFSET_92E(pDesc, offset); SET_TX_DESC_PKT_OFFSET_92E(pDesc, 1); + #endif if (bmcast) { SET_TX_DESC_BMC_92E(pDesc, 1); @@ -1484,7 +1487,8 @@ void fill_tx_desc_8192e(PADAPTER padapter) //SET_TX_DESC_QUEUE_SEL_8812(pDesc, QSLT_MGNT); if (!pattrib->qos_en) { - SET_TX_DESC_HWSEQ_SEL_92E(pDesc, 1); // Hw set sequence number + SET_TX_DESC_EN_HWSEQ_92E(pDesc, 1);// Hw set sequence number + SET_TX_DESC_HWSEQ_SEL_92E(pDesc, pattrib->hw_ssn_sel); } else { SET_TX_DESC_SEQ_92E(pDesc, pattrib->seqnum); } @@ -1508,7 +1512,6 @@ void fill_tx_desc_8192e(PADAPTER padapter) #if defined(CONFIG_RTL8723B) void fill_tx_desc_8723b(PADAPTER padapter) { - struct mp_priv *pmp_priv = &padapter->mppriv; struct pkt_attrib *pattrib = &(pmp_priv->tx.attrib); u8 *ptxdesc = pmp_priv->tx.desc; @@ -1666,16 +1669,18 @@ void SetPacketTx(PADAPTER padapter) if(pmp_priv->TXradomBuffer == NULL) { DBG_871X("mp create random buffer fail!\n"); + goto exit; } - else - { - for(i=0;i<4096;i++) - pmp_priv->TXradomBuffer[i] = rtw_random32() %0xFF; - } + + + for(i=0;i<4096;i++) + pmp_priv->TXradomBuffer[i] = rtw_random32() %0xFF; + //startPlace = (u32)(rtw_random32() % 3450); _rtw_memcpy(ptr, pmp_priv->TXradomBuffer,pkt_end - ptr); //_rtw_memset(ptr, payload, pkt_end - ptr); rtw_mfree(pmp_priv->TXradomBuffer,4096); + //3 6. start thread #ifdef PLATFORM_LINUX pmp_priv->tx.PktTxThread = kthread_run(mp_xmit_packet_thread, pmp_priv, "RTW_MP_THREAD"); @@ -1695,7 +1700,8 @@ void SetPacketTx(PADAPTER padapter) #endif Rtw_MPSetMacTxEDCA(padapter); - +exit: + return; } void SetPacketRx(PADAPTER pAdapter, u8 bStartRx) @@ -1796,7 +1802,7 @@ static u32 rtw_GetPSDData(PADAPTER pAdapter, u32 point) { u32 psd_val=0; -#if defined(CONFIG_RTL8812A) //MP PSD for 8812A +#if defined(CONFIG_RTL8812A)||defined(CONFIG_RTL8821A) //MP PSD for 8812A u16 psd_reg = 0x910; u16 psd_regL= 0xF44; @@ -2196,8 +2202,7 @@ mpt_ProQueryCalTxPower_8188E( CurrChannel = 1; } - if( pMptCtx->MptRateIndex >= MPT_RATE_1M && - pMptCtx->MptRateIndex <= MPT_RATE_11M ) + if(pMptCtx->MptRateIndex <= MPT_RATE_11M ) { TxPower = pHalData->Index24G_CCK_Base[rf_path][index]; } @@ -2241,8 +2246,7 @@ mpt_ProQueryCalTxPower_8188E( #endif // 2012/11/02 Awk: add power limit mechansim - if( pMptCtx->MptRateIndex >= MPT_RATE_1M && - pMptCtx->MptRateIndex <= MPT_RATE_11M ) + if( pMptCtx->MptRateIndex <= MPT_RATE_11M ) { rate = MGN_1M; } @@ -2273,72 +2277,141 @@ mpt_ProQueryCalTxPower_8188E( return TxPower; } -u8 MptToMgntRate(u32 MptRateIdx) + +u8 +MptToMgntRate( + IN ULONG MptRateIdx + ) { // Mapped to MGN_XXX defined in MgntGen.h switch (MptRateIdx) { /* CCK rate. */ - case MPT_RATE_1M: return 2; - case MPT_RATE_2M: return 4; - case MPT_RATE_55M: return 11; - case MPT_RATE_11M: return 22; - - /* OFDM rate. */ - case MPT_RATE_6M: return 12; - case MPT_RATE_9M: return 18; - case MPT_RATE_12M: return 24; - case MPT_RATE_18M: return 36; - case MPT_RATE_24M: return 48; - case MPT_RATE_36M: return 72; - case MPT_RATE_48M: return 96; - case MPT_RATE_54M: return 108; - - /* HT rate. */ - case MPT_RATE_MCS0: return 0x80; - case MPT_RATE_MCS1: return 0x81; - case MPT_RATE_MCS2: return 0x82; - case MPT_RATE_MCS3: return 0x83; - case MPT_RATE_MCS4: return 0x84; - case MPT_RATE_MCS5: return 0x85; - case MPT_RATE_MCS6: return 0x86; - case MPT_RATE_MCS7: return 0x87; - case MPT_RATE_MCS8: return 0x88; - case MPT_RATE_MCS9: return 0x89; - case MPT_RATE_MCS10: return 0x8A; - case MPT_RATE_MCS11: return 0x8B; - case MPT_RATE_MCS12: return 0x8C; - case MPT_RATE_MCS13: return 0x8D; - case MPT_RATE_MCS14: return 0x8E; - case MPT_RATE_MCS15: return 0x8F; - - /* VHT rate. */ - case MPT_RATE_VHT1SS_MCS0: return 0x90; - case MPT_RATE_VHT1SS_MCS1: return 0x91; - case MPT_RATE_VHT1SS_MCS2: return 0x92; - case MPT_RATE_VHT1SS_MCS3: return 0x93; - case MPT_RATE_VHT1SS_MCS4: return 0x94; - case MPT_RATE_VHT1SS_MCS5: return 0x95; - case MPT_RATE_VHT1SS_MCS6: return 0x96; - case MPT_RATE_VHT1SS_MCS7: return 0x97; - case MPT_RATE_VHT1SS_MCS8: return 0x98; - case MPT_RATE_VHT1SS_MCS9: return 0x99; - case MPT_RATE_VHT2SS_MCS0: return 0x9A; - case MPT_RATE_VHT2SS_MCS1: return 0x9B; - case MPT_RATE_VHT2SS_MCS2: return 0x9C; - case MPT_RATE_VHT2SS_MCS3: return 0x9D; - case MPT_RATE_VHT2SS_MCS4: return 0x9E; - case MPT_RATE_VHT2SS_MCS5: return 0x9F; - case MPT_RATE_VHT2SS_MCS6: return 0xA0; - case MPT_RATE_VHT2SS_MCS7: return 0xA1; - case MPT_RATE_VHT2SS_MCS8: return 0xA2; - case MPT_RATE_VHT2SS_MCS9: return 0xA3; + case MPT_RATE_1M: return MGN_1M; + case MPT_RATE_2M: return MGN_2M; + case MPT_RATE_55M: return MGN_5_5M; + case MPT_RATE_11M: return MGN_11M; + + /* OFDM rate. */ + case MPT_RATE_6M: return MGN_6M; + case MPT_RATE_9M: return MGN_9M; + case MPT_RATE_12M: return MGN_12M; + case MPT_RATE_18M: return MGN_18M; + case MPT_RATE_24M: return MGN_24M; + case MPT_RATE_36M: return MGN_36M; + case MPT_RATE_48M: return MGN_48M; + case MPT_RATE_54M: return MGN_54M; + + /* HT rate. */ + case MPT_RATE_MCS0: return MGN_MCS0; + case MPT_RATE_MCS1: return MGN_MCS1; + case MPT_RATE_MCS2: return MGN_MCS2; + case MPT_RATE_MCS3: return MGN_MCS3; + case MPT_RATE_MCS4: return MGN_MCS4; + case MPT_RATE_MCS5: return MGN_MCS5; + case MPT_RATE_MCS6: return MGN_MCS6; + case MPT_RATE_MCS7: return MGN_MCS7; + case MPT_RATE_MCS8: return MGN_MCS8; + case MPT_RATE_MCS9: return MGN_MCS9; + case MPT_RATE_MCS10: return MGN_MCS10; + case MPT_RATE_MCS11: return MGN_MCS11; + case MPT_RATE_MCS12: return MGN_MCS12; + case MPT_RATE_MCS13: return MGN_MCS13; + case MPT_RATE_MCS14: return MGN_MCS14; + case MPT_RATE_MCS15: return MGN_MCS15; + case MPT_RATE_MCS16: return MGN_MCS16; + case MPT_RATE_MCS17: return MGN_MCS17; + case MPT_RATE_MCS18: return MGN_MCS18; + case MPT_RATE_MCS19: return MGN_MCS19; + case MPT_RATE_MCS20: return MGN_MCS20; + case MPT_RATE_MCS21: return MGN_MCS21; + case MPT_RATE_MCS22: return MGN_MCS22; + case MPT_RATE_MCS23: return MGN_MCS23; + case MPT_RATE_MCS24: return MGN_MCS24; + case MPT_RATE_MCS25: return MGN_MCS25; + case MPT_RATE_MCS26: return MGN_MCS26; + case MPT_RATE_MCS27: return MGN_MCS27; + case MPT_RATE_MCS28: return MGN_MCS28; + case MPT_RATE_MCS29: return MGN_MCS29; + case MPT_RATE_MCS30: return MGN_MCS30; + case MPT_RATE_MCS31: return MGN_MCS31; + + /* VHT rate. */ + case MPT_RATE_VHT1SS_MCS0: return MGN_VHT1SS_MCS0; + case MPT_RATE_VHT1SS_MCS1: return MGN_VHT1SS_MCS1; + case MPT_RATE_VHT1SS_MCS2: return MGN_VHT1SS_MCS2; + case MPT_RATE_VHT1SS_MCS3: return MGN_VHT1SS_MCS3; + case MPT_RATE_VHT1SS_MCS4: return MGN_VHT1SS_MCS4; + case MPT_RATE_VHT1SS_MCS5: return MGN_VHT1SS_MCS5; + case MPT_RATE_VHT1SS_MCS6: return MGN_VHT1SS_MCS6; + case MPT_RATE_VHT1SS_MCS7: return MGN_VHT1SS_MCS7; + case MPT_RATE_VHT1SS_MCS8: return MGN_VHT1SS_MCS8; + case MPT_RATE_VHT1SS_MCS9: return MGN_VHT1SS_MCS9; + case MPT_RATE_VHT2SS_MCS0: return MGN_VHT2SS_MCS0; + case MPT_RATE_VHT2SS_MCS1: return MGN_VHT2SS_MCS1; + case MPT_RATE_VHT2SS_MCS2: return MGN_VHT2SS_MCS2; + case MPT_RATE_VHT2SS_MCS3: return MGN_VHT2SS_MCS3; + case MPT_RATE_VHT2SS_MCS4: return MGN_VHT2SS_MCS4; + case MPT_RATE_VHT2SS_MCS5: return MGN_VHT2SS_MCS5; + case MPT_RATE_VHT2SS_MCS6: return MGN_VHT2SS_MCS6; + case MPT_RATE_VHT2SS_MCS7: return MGN_VHT2SS_MCS7; + case MPT_RATE_VHT2SS_MCS8: return MGN_VHT2SS_MCS8; + case MPT_RATE_VHT2SS_MCS9: return MGN_VHT2SS_MCS9; + case MPT_RATE_VHT3SS_MCS0: return MGN_VHT3SS_MCS0; + case MPT_RATE_VHT3SS_MCS1: return MGN_VHT3SS_MCS1; + case MPT_RATE_VHT3SS_MCS2: return MGN_VHT3SS_MCS2; + case MPT_RATE_VHT3SS_MCS3: return MGN_VHT3SS_MCS3; + case MPT_RATE_VHT3SS_MCS4: return MGN_VHT3SS_MCS4; + case MPT_RATE_VHT3SS_MCS5: return MGN_VHT3SS_MCS5; + case MPT_RATE_VHT3SS_MCS6: return MGN_VHT3SS_MCS6; + case MPT_RATE_VHT3SS_MCS7: return MGN_VHT3SS_MCS7; + case MPT_RATE_VHT3SS_MCS8: return MGN_VHT3SS_MCS8; + case MPT_RATE_VHT3SS_MCS9: return MGN_VHT3SS_MCS9; + case MPT_RATE_VHT4SS_MCS0: return MGN_VHT4SS_MCS0; + case MPT_RATE_VHT4SS_MCS1: return MGN_VHT4SS_MCS1; + case MPT_RATE_VHT4SS_MCS2: return MGN_VHT4SS_MCS2; + case MPT_RATE_VHT4SS_MCS3: return MGN_VHT4SS_MCS3; + case MPT_RATE_VHT4SS_MCS4: return MGN_VHT4SS_MCS4; + case MPT_RATE_VHT4SS_MCS5: return MGN_VHT4SS_MCS5; + case MPT_RATE_VHT4SS_MCS6: return MGN_VHT4SS_MCS6; + case MPT_RATE_VHT4SS_MCS7: return MGN_VHT4SS_MCS7; + case MPT_RATE_VHT4SS_MCS8: return MGN_VHT4SS_MCS8; + case MPT_RATE_VHT4SS_MCS9: return MGN_VHT4SS_MCS9; - case MPT_RATE_LAST:// fully automatic - default: - DBG_8192C("<===MptToMgntRate(), Invalid Rate: %d!!\n", MptRateIdx); - return 0x0; + case MPT_RATE_LAST: // fully automatiMGN_VHT2SS_MCS1; + default: + DBG_871X("<===MptToMgntRate(), Invalid Rate: %d!!\n", MptRateIdx); + return 0x0; + } +} + +u8 rtw_mpRateParseFunc(PADAPTER pAdapter, u8 *targetStr) +{ + u16 i=0; + u8* rateindex_Array[] = { "1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M", + "HTMCS0","HTMCS1","HTMCS2","HTMCS3","HTMCS4","HTMCS5","HTMCS6","HTMCS7", + "HTMCS8","HTMCS9","HTMCS10","HTMCS11","HTMCS12","HTMCS13","HTMCS14","HTMCS15", + "HTMCS16","HTMCS17","HTMCS18","HTMCS19","HTMCS20","HTMCS21","HTMCS22","HTMCS23", + "HTMCS24","HTMCS25","HTMCS26","HTMCS27","HTMCS28","HTMCS29","HTMCS30","HTMCS31", + "VHT1MCS0","VHT1MCS1","VHT1MCS2","VHT1MCS3","VHT1MCS4","VHT1MCS5","VHT1MCS6","VHT1MCS7","VHT1MCS8","VHT1MCS9", + "VHT2MCS0","VHT2MCS1","VHT2MCS2","VHT2MCS3","VHT2MCS4","VHT2MCS5","VHT2MCS6","VHT2MCS7","VHT2MCS8","VHT2MCS9", + "VHT3MCS0","VHT3MCS1","VHT3MCS2","VHT3MCS3","VHT3MCS4","VHT3MCS5","VHT3MCS6","VHT3MCS7","VHT3MCS8","VHT3MCS9", + "VHT4MCS0","VHT4MCS1","VHT4MCS2","VHT4MCS3","VHT4MCS4","VHT4MCS5","VHT4MCS6","VHT4MCS7","VHT4MCS8","VHT4MCS9"}; + + for(i=0;i<=83;i++){ + if(strcmp(targetStr, rateindex_Array[i]) == 0){ + DBG_871X("%s , index = %d \n",__func__ ,i); + return i; + } } + + printk("%s ,please input a Data RATE String as:",__func__); + for(i=0;i<=83;i++){ + printk("%s ",rateindex_Array[i]); + if(i%10==0) + printk("\n"); + } + return _FAIL; } ULONG mpt_ProQueryCalTxPower( diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp_ioctl.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp_ioctl.c index b2c5a28aeb1c..2b4c94fbc18f 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp_ioctl.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_mp_ioctl.c @@ -21,7 +21,7 @@ #include #include -#include "../hal/OUTSRC/odm_precomp.h" +#include "../hal/OUTSRC/phydm_precomp.h" //**************** oid_rtl_seg_81_85 section start **************** NDIS_STATUS oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv) @@ -1990,9 +1990,9 @@ NDIS_STATUS oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv) psta = rtw_get_stainfo(&Adapter->stapriv, macaddr); if (psta != NULL) { - _enter_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); + //_enter_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); rtw_free_stainfo(Adapter, psta); - _exit_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); + //_exit_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); } return status; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_odm.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_odm.c index 5a40e543c237..05063bfdf990 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_odm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_odm.c @@ -37,13 +37,13 @@ const char *odm_comp_str[] = { /* BIT12 */"ODM_COMP_DYNAMIC_PRICCA", /* BIT13 */"ODM_COMP_RXHP", /* BIT14 */"ODM_COMP_MP", - /* BIT15 */"ODM_COMP_DYNAMIC_ATC", - /* BIT16 */"ODM_COMP_EDCA_TURBO", - /* BIT17 */"ODM_COMP_EARLY_MODE", + /* BIT15 */"ODM_COMP_CFO_TRACKING", + /* BIT16 */"ODM_COMP_ACS", + /* BIT17 */"PHYDM_COMP_ADAPTIVITY", /* BIT18 */NULL, /* BIT19 */NULL, - /* BIT20 */NULL, - /* BIT21 */NULL, + /* BIT20 */"ODM_COMP_EDCA_TURBO", + /* BIT21 */"ODM_COMP_EARLY_MODE", /* BIT22 */NULL, /* BIT23 */NULL, /* BIT24 */"ODM_COMP_TX_PWR_TRACK", @@ -73,14 +73,14 @@ const char *odm_ability_str[] = { /* BIT11 */"ODM_BB_PSD", /* BIT12 */"ODM_BB_RXHP", /* BIT13 */"ODM_BB_ADAPTIVITY", - /* BIT14 */"ODM_BB_DYNAMIC_ATC", - /* BIT15 */NULL, - /* BIT16 */"ODM_MAC_EDCA_TURBO", - /* BIT17 */"ODM_MAC_EARLY_MODE", + /* BIT14 */"ODM_BB_CFO_TRACKING", + /* BIT15 */"ODM_BB_NHM_CNT", + /* BIT16 */"ODM_BB_PRIMARY_CCA", + /* BIT17 */NULL, /* BIT18 */NULL, /* BIT19 */NULL, - /* BIT20 */NULL, - /* BIT21 */NULL, + /* BIT20 */"ODM_MAC_EDCA_TURBO", + /* BIT21 */"ODM_MAC_EARLY_MODE", /* BIT22 */NULL, /* BIT23 */NULL, /* BIT24 */"ODM_RF_TX_PWR_TRACK", @@ -166,6 +166,11 @@ inline void rtw_odm_ability_set(_adapter *adapter, u32 ability) rtw_hal_set_hwreg(adapter, HW_VAR_DM_FLAG, (u8*)&ability); } +void rtw_odm_adaptivity_ver_msg(void *sel, _adapter *adapter) +{ + DBG_871X_SEL_NL(sel, "ADAPTIVITY_VERSION "ADAPTIVITY_VERSION"\n"); +} + #define RTW_ADAPTIVITY_EN_DISABLE 0 #define RTW_ADAPTIVITY_EN_ENABLE 1 #define RTW_ADAPTIVITY_EN_AUTO 2 @@ -208,6 +213,25 @@ void rtw_odm_adaptivity_mode_msg(void *sel, _adapter *adapter) DBG_871X_SEL(sel, "INVALID\n"); } } + +#define RTW_NHM_EN_DISABLE 0 +#define RTW_NHM_EN_ENABLE 1 + +void rtw_odm_nhm_en_msg(void *sel, _adapter *adapter) +{ + struct registry_priv *regsty = &adapter->registrypriv; + + DBG_871X_SEL_NL(sel, "RTW_NHM_EN_"); + + if (regsty->nhm_en == RTW_NHM_EN_DISABLE) { + DBG_871X_SEL(sel, "DISABLE\n"); + } else if (regsty->nhm_en == RTW_NHM_EN_ENABLE) { + DBG_871X_SEL(sel, "ENABLE\n"); + } else { + DBG_871X_SEL(sel, "INVALID\n"); + } +} + bool rtw_odm_adaptivity_needed(_adapter *adapter) { struct registry_priv *regsty = &adapter->registrypriv; @@ -219,8 +243,10 @@ bool rtw_odm_adaptivity_needed(_adapter *adapter) ret = _TRUE; if (ret == _TRUE) { + rtw_odm_adaptivity_ver_msg(RTW_DBGDUMP, adapter); rtw_odm_adaptivity_en_msg(RTW_DBGDUMP, adapter); rtw_odm_adaptivity_mode_msg(RTW_DBGDUMP, adapter); + rtw_odm_nhm_en_msg(RTW_DBGDUMP, adapter); } return ret; @@ -231,8 +257,10 @@ void rtw_odm_adaptivity_parm_msg(void *sel, _adapter *adapter) HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); DM_ODM_T *odm = &pHalData->odmpriv; + rtw_odm_adaptivity_ver_msg(sel, adapter); rtw_odm_adaptivity_en_msg(sel, adapter); rtw_odm_adaptivity_mode_msg(sel, adapter); + rtw_odm_nhm_en_msg(sel, adapter); DBG_871X_SEL_NL(sel, "%10s %16s %8s %10s %11s %14s\n" , "TH_L2H_ini", "TH_EDCCA_HL_diff", "IGI_Base", "ForceEDCCA", "AdapEn_RSSI", "IGI_LowerBound"); @@ -244,6 +272,14 @@ void rtw_odm_adaptivity_parm_msg(void *sel, _adapter *adapter) , odm->AdapEn_RSSI , odm->IGI_LowerBound ); + + DBG_871X_SEL_NL(sel, "%8s %9s\n", "EDCCA_ES","Adap_Flag"); + DBG_871X_SEL_NL(sel, "%-8x %-9x \n" + , odm->EDCCA_enable_state + , odm->adaptivity_flag + ); + + } void rtw_odm_adaptivity_parm_set(_adapter *adapter, s8 TH_L2H_ini, s8 TH_EDCCA_HL_diff, @@ -267,4 +303,36 @@ void rtw_odm_get_perpkt_rssi(void *sel, _adapter *adapter) DBG_871X_SEL_NL(sel,"RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n", HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B); -} \ No newline at end of file +} + + +void rtw_odm_acquirespinlock(_adapter *adapter, RT_SPINLOCK_TYPE type) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + _irqL irqL; + + switch(type) + { + case RT_IQK_SPINLOCK: + _enter_critical_bh(&pdmpriv->IQKSpinLock, &irqL); + default: + break; + } +} + +void rtw_odm_releasespinlock(_adapter *adapter, RT_SPINLOCK_TYPE type) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + _irqL irqL; + + switch(type) + { + case RT_IQK_SPINLOCK: + _exit_critical_bh(&pdmpriv->IQKSpinLock, &irqL); + default: + break; + } +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_p2p.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_p2p.c index 92423bb339f0..697a69f68033 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_p2p.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_p2p.c @@ -58,6 +58,11 @@ static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf) pdata_attr = rtw_zmalloc(MAX_P2P_IE_LEN); + if(NULL == pdata_attr){ + DBG_871X("%s pdata_attr malloc failed \n", __FUNCTION__); + goto _exit; + } + pstart = pdata_attr; pcur = pdata_attr; @@ -139,7 +144,8 @@ static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf) } rtw_mfree(pdata_attr, MAX_P2P_IE_LEN); - + +_exit: return len; } @@ -3455,6 +3461,8 @@ _func_exit_; void p2p_concurrent_handler( _adapter* padapter ) { struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); //_adapter *pbuddy_adapter = padapter->pbuddy_adapter; //struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo; //struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; @@ -3495,9 +3503,12 @@ _func_enter_; } rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); - val8 = 1; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - + if(!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) && + !(pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + val8 = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } // Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not. _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period ); } @@ -3517,8 +3528,11 @@ _func_enter_; if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel ) { set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); - val8 = 0; - padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + if(!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&!(pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + val8 = 0; + padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); } @@ -3612,7 +3626,8 @@ _func_enter_; pcfg80211_wdinfo->is_ro_ch = _FALSE; pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time(); - DBG_871X("cfg80211_remain_on_channel_expired, ch=%d, bw=%d, offset=%d\n", + DBG_871X("cfg80211_remain_on_channel_expired cookie:0x%llx, ch=%d, bw=%d, offset=%d\n", + pcfg80211_wdinfo->remain_on_ch_cookie, rtw_get_oper_ch(padapter), rtw_get_oper_bw(padapter), rtw_get_oper_choffset(padapter)); rtw_cfg80211_remain_on_channel_expired(padapter, diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_pwrctrl.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_pwrctrl.c index 2076e152be14..0a16ad5c2e3b 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_pwrctrl.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_pwrctrl.c @@ -20,7 +20,8 @@ #define _RTW_PWRCTRL_C_ #include - +#include +#include int rtw_fw_ps_state(PADAPTER padapter) { @@ -159,6 +160,9 @@ int ips_leave(_adapter * padapter) #endif //DBG_CHECK_FW_PS_STATE _exit_pwrlock(&pwrpriv->lock); + if (_SUCCESS == ret) + ODM_DMReset(&GET_HAL_DATA(padapter)->odmpriv); + #ifdef CONFIG_BT_COEXIST if (_SUCCESS == ret) rtw_btcoex_IpsNotify(padapter, IPS_NONE); @@ -460,7 +464,7 @@ void traffic_check_for_leave_lps(PADAPTER padapter, u8 tx, u32 tx_packets) #endif ) { - DBG_871X("leave lps via Tx = %d\n", xmit_cnt); + //DBG_871X("leave lps via Tx = %d\n", xmit_cnt); bLeaveLPS = _TRUE; } } @@ -481,7 +485,7 @@ void traffic_check_for_leave_lps(PADAPTER padapter, u8 tx, u32 tx_packets) #endif ) { - DBG_871X("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); + //DBG_871X("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); bLeaveLPS = _TRUE; } } @@ -491,7 +495,7 @@ void traffic_check_for_leave_lps(PADAPTER padapter, u8 tx, u32 tx_packets) { //DBG_871X("leave lps via %s, Tx = %d, Rx = %d \n", tx?"Tx":"Rx", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); //rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1); - rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, tx?0:1); + rtw_lps_ctrl_wk_cmd(padapter, tx?LPS_CTRL_TX_TRAFFIC_LEAVE:LPS_CTRL_RX_TRAFFIC_LEAVE, tx?0:1); } #endif //CONFIG_CHECK_LEAVE_LPS } @@ -604,7 +608,7 @@ _func_enter_; // polling cpwm do { - rtw_mdelay_os(1); + rtw_msleep_os(1); poll_cnt++; rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now); if ((cpwm_orig ^ cpwm_now) & 0x80) @@ -718,6 +722,141 @@ u8 PS_RDY_CHECK(_adapter * padapter) return _TRUE; } +#if defined(CONFIG_FWLPS_IN_IPS) && defined(CONFIG_PNO_SUPPORT) +void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable) +{ + struct hal_ops *pHalFunc = &padapter->HalFunc; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + int cnt=0; + u32 start_time; + u8 val8 = 0; + u8 cpwm_orig, cpwm_now; + u8 parm[H2C_INACTIVE_PS_LEN]={0}; + + if (padapter->netif_up == _FALSE) { + DBG_871X("%s: ERROR, netif is down\n", __func__); + return; + } + + if (pHalFunc->fill_h2c_cmd == NULL) { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + return; + } + + //u8 cmd_param; //BIT0:enable, BIT1:NoConnect32k + if (enable) { + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req); +#endif + //Enter IPS + DBG_871X("%s: issue H2C to FW when entering IPS\n", __func__); + parm[0] = 0x03; + parm[1] = 0x01; + parm[2] = 0x01; + pHalFunc->fill_h2c_cmd(padapter, //H2C_FWLPS_IN_IPS_, + H2C_INACTIVE_PS_, + H2C_INACTIVE_PS_LEN, parm); + //poll 0x1cc to make sure H2C command already finished by FW; MAC_0x1cc=0 means H2C done by FW. + do{ + val8 = rtw_read8(padapter, REG_HMETFR); + cnt++; + DBG_871X("%s polling REG_HMETFR=0x%x, cnt=%d \n", + __func__, val8, cnt); + rtw_mdelay_os(10); + }while(cnt<100 && (val8!=0)); + + //H2C done, enter 32k + if (val8 == 0) { + //ser rpwm to enter 32k + val8 = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1); + DBG_871X("%s: read rpwm=%02x\n", __FUNCTION__, val8); + val8 += 0x80; + val8 |= BIT(0); + rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8); + DBG_871X("%s: write rpwm=%02x\n", __FUNCTION__, val8); + adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80; + cnt = val8 = 0; + do { + val8 = rtw_read8(padapter, REG_CR); + cnt++; + DBG_871X("%s polling 0x100=0x%x, cnt=%d \n", + __func__, val8, cnt); + DBG_871X("%s 0x08:%02x, 0x03:%02x\n", + __func__, + rtw_read8(padapter, 0x08), + rtw_read8(padapter, 0x03)); + rtw_mdelay_os(10); + } while(cnt<20 && (val8!=0xEA)); +#ifdef DBG_CHECK_FW_PS_STATE + if(val8 != 0xEA) { + DBG_871X("MAC_1B8=0x%08x\n", + rtw_read32(padapter, 0x1b8)); + DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", + rtw_read32(padapter, 0x1c0), + rtw_read32(padapter, 0x1c4), + rtw_read32(padapter, 0x1c8), + rtw_read32(padapter, 0x1cc)); +#endif //DBG_CHECK_FW_PS_STATE + } else { + DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", + rtw_read32(padapter, 0x1c0), + rtw_read32(padapter, 0x1c4), + rtw_read32(padapter, 0x1c8), + rtw_read32(padapter, 0x1cc)); + } + } + } else { + //Leave IPS + DBG_871X("%s: Leaving IPS in FWLPS state\n", __func__); + + //for polling cpwm + cpwm_orig = 0; + rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig); + + //ser rpwm + val8 = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1); + val8 &= 0x80; + val8 += 0x80; + val8 |= BIT(6); + rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8); + DBG_871X("%s: write rpwm=%02x\n", __FUNCTION__, val8); + adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80; + + //do polling cpwm + start_time = rtw_get_current_time(); + do { + + rtw_mdelay_os(1); + + rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now); + if ((cpwm_orig ^ cpwm_now) & 0x80) { +#ifdef DBG_CHECK_FW_PS_STATE + DBG_871X("%s: polling cpwm ok when leaving IPS in FWLPS state, cpwm_orig=%02x, cpwm_now=%02x, 0x100=0x%x \n" + , __FUNCTION__, cpwm_orig, cpwm_now, rtw_read8(padapter, REG_CR)); +#endif //DBG_CHECK_FW_PS_STATE + break; + } + + if (rtw_get_passing_time_ms(start_time) > 100) + { + DBG_871X("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __FUNCTION__); + break; + } + } while (1); + + parm[0] = 0x0; + parm[1] = 0x0; + parm[2] = 0x0; + pHalFunc->fill_h2c_cmd(padapter, H2C_INACTIVE_PS_, + H2C_INACTIVE_PS_LEN, parm); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_IpsNotify(padapter, IPS_NONE); +#endif + } +} +#endif //CONFIG_PNO_SUPPORT + void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); @@ -809,9 +948,10 @@ _func_enter_; pwrpriv->pwr_mode = ps_mode; rtw_set_rpwm(padapter, PS_STATE_S4); -#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN) if (pwrpriv->wowlan_mode == _TRUE || - pwrpriv->wowlan_ap_mode == _TRUE) + pwrpriv->wowlan_ap_mode == _TRUE || + pwrpriv->wowlan_p2p_mode == _TRUE) { u32 start_time, delay_ms; u8 val8; @@ -849,6 +989,9 @@ _func_enter_; || ((rtw_btcoex_IsBtControlLps(padapter) == _TRUE) && (rtw_btcoex_IsLpsOn(padapter) == _TRUE)) #endif +#ifdef CONFIG_P2P_WOWLAN + ||( _TRUE == pwrpriv->wowlan_p2p_mode) +#endif //CONFIG_P2P_WOWLAN ) { u8 pslv; @@ -1015,6 +1158,13 @@ _func_enter_; return; } +#ifdef CONFIG_P2P_PS + if(padapter->wdinfo.p2p_ps_mode == P2P_PS_NOA) + { + return;//supporting p2p client ps NOA via H2C_8723B_P2P_PS_OFFLOAD + } +#endif //CONFIG_P2P_PS + if (pwrpriv->bLeisurePs) { // Idle for a while if we connect to AP a while ago. @@ -2148,6 +2298,7 @@ _func_enter_; pwrctrlpriv->wowlan_mode = _FALSE; pwrctrlpriv->wowlan_ap_mode = _FALSE; + pwrctrlpriv->wowlan_p2p_mode = _FALSE; #ifdef CONFIG_RESUME_IN_WORKQUEUE _init_workitem(&pwrctrlpriv->resume_work, resume_workitem_callback, NULL); @@ -2159,6 +2310,9 @@ _func_enter_; rtw_register_early_suspend(pwrctrlpriv); #endif //CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER +#ifdef CONFIG_WOWLAN + pwrctrlpriv->wowlan_from_cmd = _FALSE; +#endif #ifdef CONFIG_PNO_SUPPORT pwrctrlpriv->pno_inited = _FALSE; pwrctrlpriv->pnlo_info = NULL; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_recv.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_recv.c index bee356f8cc3d..a5e4e2d4a333 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_recv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_recv.c @@ -75,6 +75,10 @@ _func_enter_; precvpriv->free_recvframe_cnt = NR_RECVFRAME; + precvpriv->sink_udpport = 0; + precvpriv->pre_rtp_rxseq = 0; + precvpriv->cur_rtp_rxseq = 0; + rtw_os_recv_resource_init(precvpriv, padapter); precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); @@ -109,7 +113,7 @@ _func_enter_; #ifdef CONFIG_USB_HCI - precvpriv->rx_pending_cnt=1; + ATOMIC_SET(&(precvpriv->rx_pending_cnt), 1); _rtw_init_sema(&precvpriv->allrxreturnevt, 0); @@ -1580,6 +1584,32 @@ _func_enter_; goto exit; } } + else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && + (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ) + { + DBG_871X("%s ,in WIFI_MP_STATE \n",__func__); + + _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + // + _rtw_memcpy(pattrib->bssid, mybssid, ETH_ALEN); + + + *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); // get sta_info + if (*psta == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under MP_MODE ; drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __FUNCTION__); + #endif + ret= _FAIL; + goto exit; + } + + } else { u8 *myhwaddr = myid(&adapter->eeprompriv); if (!_rtw_memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) { @@ -1745,7 +1775,7 @@ sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame) DBG_871X("no buffered packets to xmit\n"); //issue nulldata with More data bit = 0 to indicate we have no buffered packets - issue_nulldata_in_interrupt(padapter, psta->hwaddr); + issue_nulldata_in_interrupt(padapter, psta->hwaddr, 0); } else { @@ -2086,7 +2116,7 @@ static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_fram DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __FUNCTION__); goto validate_80211w_fail; } - /*//dump the packet content before decrypt + /* //dump the packet content before decrypt { int pp; printk("pattrib->pktlen = %d =>", pattrib->pkt_len); @@ -2103,7 +2133,7 @@ static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_fram //remove the iv and icv length pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len; rtw_mfree(mgmt_DATA, data_len); - /*//print packet content after decryption + /* //print packet content after decryption { int pp; printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len); @@ -2130,9 +2160,9 @@ static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_fram } else if(BIP_ret == RTW_RX_HANDLED) { - //DBG_871X("802.11w recv none protected packet\n"); - //issue sa query request - issue_action_SA_Query(adapter, NULL, 0, 0); + DBG_871X("802.11w recv none protected packet\n"); + //drop pkt, don't issue sa query request + //issue_action_SA_Query(adapter, NULL, 0, 0); goto validate_80211w_fail; } }//802.11w protect @@ -2153,9 +2183,14 @@ static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_fram } else if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) { - DBG_871X("802.11w recv none protected packet\n"); - //issue sa query request - issue_action_SA_Query(adapter, NULL, 0, 0); + unsigned short reason; + reason = le16_to_cpu(*(unsigned short *)(ptr + WLAN_HDR_A3_LEN)); + DBG_871X("802.11w recv none protected packet, reason=%d\n", reason); + if(reason == 6 || reason == 7) + { + //issue sa query request + issue_action_SA_Query(adapter, NULL, 0, 0); + } goto validate_80211w_fail; } } @@ -2486,21 +2521,32 @@ _func_enter_; eth_type = 0x8712; // append rx status for mp test packets ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24); + if (!ptr) { + ret = _FAIL; + goto exiting; + } _rtw_memcpy(ptr, get_rxmem(precvframe), 24); ptr+=24; } else { ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+ (bsnaphdr?2:0))); + if (!ptr) { + ret = _FAIL; + goto exiting; + } } - _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); - _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); + if (ptr) { + _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); + _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); - if(!bsnaphdr) { - len = htons(len); - _rtw_memcpy(ptr+12, &len, 2); + if(!bsnaphdr) { + len = htons(len); + _rtw_memcpy(ptr+12, &len, 2); + } } +exiting: _func_exit_; return ret; @@ -3342,7 +3388,15 @@ int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe) if(!pattrib->amsdu) { //s1. - wlanhdr_to_ethhdr(prframe); + retval = wlanhdr_to_ethhdr(prframe); + if (retval != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("wlanhdr_to_ethhdr: drop pkt \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __FUNCTION__); + #endif + return retval; + } //if ((pattrib->qos!=1) /*|| pattrib->priority!=0 || IS_MCAST(pattrib->ra)*/ // || (pattrib->eth_type==0x0806) || (pattrib->ack_policy!=0)) @@ -3643,6 +3697,77 @@ int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame) } #endif +static sint MPwlanhdr_to_ethhdr ( union recv_frame *precvframe) +{ + sint rmv_len; + u16 eth_type, len; + u8 bsnaphdr; + u8 *psnap_type; + struct ieee80211_snap_hdr *psnap; + + sint ret=_SUCCESS; + _adapter *adapter =precvframe->u.hdr.adapter; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + + u8 *ptr = get_recvframe_data(precvframe) ; // point to frame_ctrl field + struct rx_pkt_attrib *pattrib = & precvframe->u.hdr.attrib; + +_func_enter_; + + if(pattrib->encrypt){ + recvframe_pull_tail(precvframe, pattrib->icv_len); + } + + psnap=(struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + pattrib->iv_len); + psnap_type=ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + /* convert hdr + possible LLC headers into Ethernet header */ + //eth_type = (psnap_type[0] << 8) | psnap_type[1]; + if((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && + (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) && + (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)==_FALSE) )|| + //eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || + _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)){ + /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ + bsnaphdr = _TRUE; + } + else { + /* Leave Ethernet header part of hdr and full payload */ + bsnaphdr = _FALSE; + } + + rmv_len = pattrib->hdrlen + pattrib->iv_len +(bsnaphdr?SNAP_SIZE:0); + len = precvframe->u.hdr.len - rmv_len; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n\n", pattrib->hdrlen, pattrib->iv_len)); + + _rtw_memcpy(ð_type, ptr+rmv_len, 2); + eth_type= ntohs((unsigned short )eth_type); //pattrib->ether_type + pattrib->eth_type = eth_type; + + { + ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+ (bsnaphdr?2:0))); + } + + _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); + _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); + + if(!bsnaphdr) { + len = htons(len); + _rtw_memcpy(ptr+12, &len, 2); + } + + if (adapter->registrypriv.mp_mode == 1) + { + len = htons(pattrib->seq_num); + //DBG_871X("wlan seq = %d ,seq_num =%x\n",len,pattrib->seq_num); + _rtw_memcpy(ptr+12,&len, 2); + } +_func_exit_; + return ret; + +} + + int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe) { int ret = _SUCCESS; @@ -3653,13 +3778,17 @@ int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mp_priv *pmppriv = &padapter->mppriv; #endif //CONFIG_MP_INCLUDED - - DBG_COUNTER(padapter->rx_logs.core_rx_pre); + u8 type; + u8 *ptr = rframe->u.hdr.rx_data; + u8 *psa, *pda, *pbssid; + struct sta_info *psta = NULL; + DBG_COUNTER(padapter->rx_logs.core_rx_pre); #ifdef CONFIG_MP_INCLUDED if (padapter->registrypriv.mp_mode == 1) { - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0)) + + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) )//&&(padapter->mppriv.check_mp_pkt == 0)) { if (pattrib->crc_err == 1){ padapter->mppriv.rx_crcerrpktcount++; @@ -3671,18 +3800,125 @@ int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe) padapter->mppriv.rx_pktcount_filter_out++; } - + if(pmppriv->rx_bindicatePkt == _FALSE) { - if (check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE) == _FALSE) { + //if (check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE) == _FALSE) { //RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("MP - Not in loopback mode , drop pkt \n")); ret = _FAIL; rtw_free_recvframe(rframe, pfree_recv_queue);//free this recv_frame goto exit; - } + } - } - } + else { + + type = GetFrameType(ptr); + pattrib->to_fr_ds = get_tofr_ds(ptr); + pattrib->frag_num = GetFragNum(ptr); + pattrib->seq_num = GetSequence(ptr); + pattrib->pw_save = GetPwrMgt(ptr); + pattrib->mfrag = GetMFrag(ptr); + pattrib->mdata = GetMData(ptr); + pattrib->privacy = GetPrivacy(ptr); + pattrib->order = GetOrder(ptr); + + if(type ==WIFI_DATA_TYPE) + { + pda = get_da(ptr); + psa = get_sa(ptr); + pbssid = get_hdr_bssid(ptr); + + _rtw_memcpy(pattrib->dst, pda, ETH_ALEN); + _rtw_memcpy(pattrib->src, psa, ETH_ALEN); + _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN); + + switch(pattrib->to_fr_ds) + { + case 0: + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); + ret = sta2sta_data_frame(padapter, rframe, &psta); + break; + + case 1: + + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); + ret = ap2sta_data_frame(padapter, rframe, &psta); + + break; + + case 2: + _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN); + _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); + ret = sta2ap_data_frame(padapter, rframe, &psta); + break; + + case 3: + _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); + ret =_FAIL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" case 3\n")); + break; + + default: + ret =_FAIL; + break; + } + + ret = MPwlanhdr_to_ethhdr (rframe); + + if (ret != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("wlanhdr_to_ethhdr: drop pkt \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr: drop pkt\n", __FUNCTION__); + #endif + rtw_free_recvframe(rframe, pfree_recv_queue);//free this recv_frame + ret = _FAIL; + goto exit; + } + + if ((padapter->bDriverStopped == _FALSE) && (padapter->bSurpriseRemoved == _FALSE)) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@ recv_func: recv_func rtw_recv_indicatepkt\n" )); + //indicate this recv_frame + ret = rtw_recv_indicatepkt(padapter, rframe); + if (ret != _SUCCESS) + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__); + #endif + rtw_free_recvframe(rframe, pfree_recv_queue);//free this recv_frame + ret = _FAIL; + + goto exit; + } + } + else + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@ recv_func: rtw_free_recvframe\n" )); + RT_TRACE(_module_rtl871x_recv_c_, _drv_debug_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved)); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s ecv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", __FUNCTION__, + padapter->bDriverStopped, padapter->bSurpriseRemoved); + #endif + ret = _FAIL; + rtw_free_recvframe(rframe, pfree_recv_queue);//free this recv_frame + goto exit; + } + + } + } + + } + + RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n")); + rtw_free_recvframe(rframe, pfree_recv_queue);//free this recv_frame + ret = _FAIL; + goto exit; + } + #endif //check the frame crtl field and decache diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sreset.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sreset.c index 82db59c670dd..c7066f8fb9eb 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sreset.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sreset.c @@ -267,8 +267,7 @@ void sreset_stop_adapter(_adapter *padapter) DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - if (!rtw_netif_queue_stopped(padapter->pnetdev)) - rtw_netif_stop_queue(padapter->pnetdev); + rtw_netif_stop_queue(padapter->pnetdev); rtw_cancel_all_timer(padapter); @@ -307,11 +306,10 @@ void sreset_start_adapter(_adapter *padapter) tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); #endif - _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); - - if (rtw_netif_queue_stopped(padapter->pnetdev)) - rtw_netif_wake_queue(padapter->pnetdev); + if (is_primary_adapter(padapter)) + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); + rtw_netif_wake_queue(padapter->pnetdev); } void sreset_reset(_adapter *padapter) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sta_mgt.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sta_mgt.c index f03f727d9ee6..f17b2a2dc475 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sta_mgt.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_sta_mgt.c @@ -456,13 +456,19 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) struct xmit_priv *pxmitpriv= &padapter->xmitpriv; struct sta_priv *pstapriv = &padapter->stapriv; struct hw_xmit *phwxmit; - + int pending_qcnt[4]; _func_enter_; if (psta == NULL) goto exit; + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL0); + rtw_list_delete(&psta->hash_list); + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",pstapriv->asoc_sta_count , psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5])); + pstapriv->asoc_sta_count --; + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL0); + _enter_critical_bh(&psta->lock, &irqL0); psta->state &= ~_FW_LINKED; @@ -488,6 +494,7 @@ _func_enter_; rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending)); phwxmit = pxmitpriv->hwxmits; phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt; + pending_qcnt[0] = pstaxmitpriv->vo_q.qcnt; pstaxmitpriv->vo_q.qcnt = 0; //_exit_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0); @@ -497,6 +504,7 @@ _func_enter_; rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending)); phwxmit = pxmitpriv->hwxmits+1; phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt; + pending_qcnt[1] = pstaxmitpriv->vi_q.qcnt; pstaxmitpriv->vi_q.qcnt = 0; //_exit_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0); @@ -506,6 +514,7 @@ _func_enter_; rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending)); phwxmit = pxmitpriv->hwxmits+2; phwxmit->accnt -= pstaxmitpriv->be_q.qcnt; + pending_qcnt[2] = pstaxmitpriv->be_q.qcnt; pstaxmitpriv->be_q.qcnt = 0; //_exit_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0); @@ -515,15 +524,14 @@ _func_enter_; rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending)); phwxmit = pxmitpriv->hwxmits+3; phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt; + pending_qcnt[3] = pstaxmitpriv->bk_q.qcnt; pstaxmitpriv->bk_q.qcnt = 0; //_exit_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0); - + + rtw_os_wake_queue_at_free_stainfo(padapter, pending_qcnt); + _exit_critical_bh(&pxmitpriv->lock, &irqL0); - rtw_list_delete(&psta->hash_list); - RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",pstapriv->asoc_sta_count , psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5])); - pstapriv->asoc_sta_count --; - // re-init sta_info; 20061114 // will be init in alloc_stainfo //_rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); @@ -631,7 +639,9 @@ _func_enter_; _rtw_spinlock_free(&psta->lock); //_enter_critical_bh(&(pfree_sta_queue->lock), &irqL0); + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL0); rtw_list_insert_tail(&psta->list, get_list_head(pfree_sta_queue)); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL0); //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL0); exit: @@ -651,6 +661,9 @@ void rtw_free_all_stainfo(_adapter *padapter) struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info* pbcmc_stainfo =rtw_get_bcmc_stainfo( padapter); + u8 free_sta_num = 0; + char free_sta_list[NUM_STA]; + int stainfo_offset; _func_enter_; @@ -670,13 +683,27 @@ _func_enter_; plist = get_next(plist); - if(pbcmc_stainfo!=psta) - rtw_free_stainfo(padapter , psta); + if(pbcmc_stainfo!=psta) + { + rtw_list_delete(&psta->hash_list); + //rtw_free_stainfo(padapter , psta); + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + free_sta_list[free_sta_num++] = stainfo_offset; + } + } } } _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + + for (index = 0; index < free_sta_num; index++) + { + psta = rtw_get_stainfo_by_offset(pstapriv, free_sta_list[index]); + rtw_free_stainfo(padapter , psta); + } exit: @@ -762,9 +789,6 @@ _func_enter_; goto exit; } - // default broadcast & multicast use macid 1 - psta->mac_id = 1; - ptxservq= &(psta->sta_xmitpriv.be_q); /* diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_wlan_util.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_wlan_util.c index e3f1fed10f8d..c2e4e48dddc9 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_wlan_util.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_wlan_util.c @@ -70,6 +70,7 @@ static u8 rtw_basic_rate_mix[7] = { IEEE80211_OFDM_RATE_24MB|IEEE80211_BASIC_RATE_MASK }; +int new_bcn_max = 3; int cckrates_included(unsigned char *rate, int ratelen) { @@ -862,8 +863,9 @@ void invalidate_cam_all(_adapter *padapter) struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; _irqL irqL; + u8 val8 = 0; - rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, 0); + rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, &val8); _enter_critical_bh(&cam_ctl->lock, &irqL); cam_ctl->bitmap = 0; @@ -900,6 +902,32 @@ void read_cam(_adapter *padapter ,u8 entry, u8 *get_key) } //DBG_8192C("*********************************\n"); } + +bool read_phy_cam_is_gtk(_adapter *padapter, u8 entry) +{ + bool res = _FALSE; + u32 addr, cmd; + + addr = entry << 3; + cmd = _ReadCAM(padapter, addr); + + res = (cmd & BIT6)? _TRUE:_FALSE; + return res; +} + +void dump_cam_table(_adapter *padapter) { + u32 i, j, addr, cmd; + DBG_871X("###########DUMP CAM TABLE##############\n"); + for (i = 0; i < 8 ; i++) { + addr = i << 3; + DBG_871X("********* DUMP CAM Entry_#%02d**********\n",i); + for (j = 0; j < 6; j++) { + cmd = _ReadCAM(padapter ,addr+j); + DBG_8192C("offset:0x%02x => 0x%08x \n",addr+j,cmd); + } + DBG_871X("*********************************\n"); + } +} #endif void _write_cam(_adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key) @@ -1656,7 +1684,9 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) } else { - //modify from fw by Thomas 2010/11/17 + /* AMPDU Parameters field */ + + /* Get MIN of MAX AMPDU Length Exp */ if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3)) { max_AMPDU_len = (pIE->data[i] & 0x3); @@ -1665,7 +1695,8 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) { max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3); } - + + /* Get MAX of MIN MPDU Start Spacing */ if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c)) { min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c); @@ -1713,7 +1744,7 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { // Config STBC setting - if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAPABILITY_ELE_TX_STBC(pIE->data)) + if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_TX_STBC(pIE->data)) { SET_FLAG(cur_stbc_cap, STBC_HT_ENABLE_TX); DBG_871X("Enable HT Tx STBC !\n"); @@ -1740,7 +1771,7 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) #endif //CONFIG_BEAMFORMING } else { // Config LDPC Coding Capability - if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAPABILITY_ELE_LDPC_CAP(pIE->data)) + if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAP_ELE_LDPC_CAP(pIE->data)) { SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX)); DBG_871X("Enable HT Tx LDPC!\n"); @@ -1748,7 +1779,7 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) phtpriv->ldpc_cap = cur_ldpc_cap; // Config STBC setting - if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAPABILITY_ELE_RX_STBC(pIE->data)) + if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(pIE->data)) { SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX) ); DBG_871X("Enable HT Tx STBC!\n"); @@ -1994,8 +2025,117 @@ int check_ap_tdls_prohibited(u8 *pframe, u8 pkt_len) } #endif //CONFIG_TDLS +/* + * rtw_get_bcn_keys: get beacon keys from recv frame + * + * TODO: + * WLAN_EID_COUNTRY + * WLAN_EID_ERP_INFO + * WLAN_EID_CHANNEL_SWITCH + * WLAN_EID_PWR_CONSTRAINT + */ +int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, + struct beacon_keys *recv_beacon) +{ + int left; + u16 capability; + unsigned char *pos; + struct rtw_ieee802_11_elems elems; + struct rtw_ieee80211_ht_cap *pht_cap = NULL; + struct HT_info_element *pht_info = NULL; + + _rtw_memset(recv_beacon, 0, sizeof(*recv_beacon)); + + /* checking capabilities */ + capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 10)); + + /* checking IEs */ + left = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_; + pos = pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_; + if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) + return _FALSE; + + /* check bw and channel offset */ + if (elems.ht_capabilities) { + if (elems.ht_capabilities_len != sizeof(*pht_cap)) + return _FALSE; + + pht_cap = (struct rtw_ieee80211_ht_cap *) elems.ht_capabilities; + recv_beacon->ht_cap_info = pht_cap->cap_info; + } + + if (elems.ht_operation) { + if (elems.ht_operation_len != sizeof(*pht_info)) + return _FALSE; + + pht_info = (struct HT_info_element *) elems.ht_operation; + recv_beacon->ht_info_infos_0_sco = pht_info->infos[0] & 0x03; + } + + /* Checking for channel */ + if (elems.ds_params && elems.ds_params_len == sizeof(recv_beacon->bcn_channel)) + _rtw_memcpy(&recv_beacon->bcn_channel, elems.ds_params, + sizeof(recv_beacon->bcn_channel)); + else if (pht_info) + /* In 5G, some ap do not have DSSET IE checking HT info for channel */ + recv_beacon->bcn_channel = pht_info->primary_channel; + else { + /* we don't find channel IE, so don't check it */ + //DBG_871X("Oops: %s we don't find channel IE, so don't check it \n", __func__); + recv_beacon->bcn_channel = Adapter->mlmeextpriv.cur_channel; + } + + /* checking SSID */ + if (elems.ssid) { + if (elems.ssid_len > sizeof(recv_beacon->ssid)) + return _FALSE; + + _rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len); + recv_beacon->ssid_len = elems.ssid_len; + } else; // means hidden ssid + + /* checking RSN first */ + if (elems.rsn_ie && elems.rsn_ie_len) { + recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2; + rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2, + &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher, + &recv_beacon->is_8021x); + } + /* checking WPA secon */ + else if (elems.wpa_ie && elems.wpa_ie_len) { + recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA; + rtw_parse_wpa_ie(elems.wpa_ie - 2, elems.wpa_ie_len + 2, + &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher, + &recv_beacon->is_8021x); + } + else if (capability & BIT(4)) { + recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP; + } + + return _TRUE; +} + +void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon) +{ + int i; + char *p; + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + + _rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len); + ssid[recv_beacon->ssid_len] = '\0'; + + DBG_871X("%s: ssid = %s\n", __func__, ssid); + DBG_871X("%s: channel = %x\n", __func__, recv_beacon->bcn_channel); + DBG_871X("%s: ht_cap = %x\n", __func__, recv_beacon->ht_cap_info); + DBG_871X("%s: ht_info_infos_0_sco = %x\n", __func__, recv_beacon->ht_info_infos_0_sco); + DBG_871X("%s: sec=%d, group = %x, pair = %x, 8021X = %x\n", __func__, + recv_beacon->encryp_protocol, recv_beacon->group_cipher, + recv_beacon->pairwise_cipher, recv_beacon->is_8021x); +} + int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) { +#if 0 unsigned int len; unsigned char *p; unsigned short val16, subtype; @@ -2015,7 +2155,12 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) u32 bcn_channel; unsigned short ht_cap_info; unsigned char ht_info_infos_0; +#endif + unsigned int len; + u8 *pbssid = GetAddr3Ptr(pframe); struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network); + struct beacon_keys recv_beacon; if (is_client_associated_to_ap(Adapter) == _FALSE) return _TRUE; @@ -2033,6 +2178,78 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) return _TRUE; } + if (rtw_get_bcn_keys(Adapter, pframe, packet_len, &recv_beacon) == _FALSE) + return _TRUE; // parsing failed => broken IE + + // don't care hidden ssid, use current beacon ssid directly + if (recv_beacon.ssid_len == 0) { + _rtw_memcpy(recv_beacon.ssid, pmlmepriv->cur_beacon_keys.ssid, + pmlmepriv->cur_beacon_keys.ssid_len); + recv_beacon.ssid_len = pmlmepriv->cur_beacon_keys.ssid_len; + } + + if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _TRUE) + { + pmlmepriv->new_beacon_cnts = 0; + } + else if ((pmlmepriv->new_beacon_cnts == 0) || + _rtw_memcmp(&recv_beacon, &pmlmepriv->new_beacon_keys, sizeof(recv_beacon)) == _FALSE) + { + DBG_871X_LEVEL(_drv_err_, "%s: start new beacon (seq=%d)\n", __func__, GetSequence(pframe)); + + if (pmlmepriv->new_beacon_cnts == 0) { + DBG_871X_LEVEL(_drv_err_, "%s: cur beacon key\n", __func__); + DBG_871X_EXP(_drv_err_, rtw_dump_bcn_keys(&pmlmepriv->cur_beacon_keys)); + } + + DBG_871X_LEVEL(_drv_err_, "%s: new beacon key\n", __func__); + DBG_871X_EXP(_drv_err_, rtw_dump_bcn_keys(&recv_beacon)); + + memcpy(&pmlmepriv->new_beacon_keys, &recv_beacon, sizeof(recv_beacon)); + pmlmepriv->new_beacon_cnts = 1; + } + else + { + DBG_871X_LEVEL(_drv_err_, "%s: new beacon again (seq=%d)\n", __func__, GetSequence(pframe)); + pmlmepriv->new_beacon_cnts++; + } + + // if counter >= max, it means beacon is changed really + if (pmlmepriv->new_beacon_cnts >= new_bcn_max) + { + DBG_871X_LEVEL(_drv_err_, "%s: new beacon occur!!\n", __func__); + + // check bw mode change only? + pmlmepriv->cur_beacon_keys.ht_cap_info = recv_beacon.ht_cap_info; + pmlmepriv->cur_beacon_keys.ht_info_infos_0_sco = recv_beacon.ht_info_infos_0_sco; + + if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, + sizeof(recv_beacon)) == _FALSE) { + // beacon is changed, have to do disconnect/connect + return _FAIL; + } + + DBG_871X("%s bw mode change\n", __func__); + DBG_871X("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, + cur_network->BcnInfo.ht_cap_info, + cur_network->BcnInfo.ht_info_infos_0); + + cur_network->BcnInfo.ht_cap_info = recv_beacon.ht_cap_info; + cur_network->BcnInfo.ht_info_infos_0 = + (cur_network->BcnInfo.ht_info_infos_0 & (~0x03)) | + recv_beacon.ht_info_infos_0_sco; + + DBG_871X("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, + cur_network->BcnInfo.ht_cap_info, + cur_network->BcnInfo.ht_info_infos_0); + + memcpy(&pmlmepriv->cur_beacon_keys, &recv_beacon, sizeof(recv_beacon)); + pmlmepriv->new_beacon_cnts = 0; + } + + return _SUCCESS; + +#if 0 bssid = (WLAN_BSSID_EX *)rtw_zmalloc(sizeof(WLAN_BSSID_EX)); if (bssid == NULL) { DBG_871X("%s rtw_zmalloc fail !!!\n", __func__); @@ -2229,6 +2446,7 @@ _mismatch: } return _SUCCESS; +#endif } void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta) @@ -3127,8 +3345,8 @@ void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) /pmlmeext->bcn_cnt; - DBG_871X("%s():bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d]=%d\n", __func__, i, - pmlmeext->bcn_delay_cnt[i] , i, pmlmeext->bcn_delay_ratio[i]); + //DBG_871X("%s():bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d]=%d\n", __func__, i, + // pmlmeext->bcn_delay_cnt[i] , i, pmlmeext->bcn_delay_ratio[i]); ratio_20_delay += pmlmeext->bcn_delay_ratio[i]; ratio_80_delay += pmlmeext->bcn_delay_ratio[i]; @@ -3136,13 +3354,13 @@ void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) if(ratio_20_delay > 20 && DrvBcnEarly == 0xff) { DrvBcnEarly = i; - DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, DrvBcnEarly); + //DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, DrvBcnEarly); } if(ratio_80_delay > 80 && DrvBcnTimeOut == 0xff) { DrvBcnTimeOut = i; - DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, DrvBcnTimeOut); + //DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, DrvBcnTimeOut); } //reset adaptive_early_32k cnt @@ -3164,99 +3382,278 @@ void beacon_timing_control(_adapter *padapter) rtw_hal_bcn_related_reg_setting(padapter); } +#define CONFIG_SHARED_BMC_MACID + +void dump_macid_map(void *sel, struct macid_bmp *map, u8 max_num) +{ + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m0); +#if (MACID_NUM_SW_LIMIT > 32) + if (max_num && max_num > 32) + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m1); +#endif +#if (MACID_NUM_SW_LIMIT > 64) + if (max_num && max_num > 64) + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m2); +#endif +#if (MACID_NUM_SW_LIMIT > 96) + if (max_num && max_num > 96) + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m3); +#endif +} + +inline bool rtw_macid_is_set(struct macid_bmp *map, u8 id) +{ + if (id < 32) + return (map->m0 & BIT(id)); +#if (MACID_NUM_SW_LIMIT > 32) + else if (id < 64) + return (map->m1 & BIT(id-32)); +#endif +#if (MACID_NUM_SW_LIMIT > 64) + else if (id < 96) + return (map->m2 & BIT(id-64)); +#endif +#if (MACID_NUM_SW_LIMIT > 96) + else if (id < 128) + return (map->m3 & BIT(id-96)); +#endif + else + rtw_warn_on(1); + + return 0; +} + +inline void rtw_macid_map_set(struct macid_bmp *map, u8 id) +{ + if (id < 32) + map->m0 |= BIT(id); +#if (MACID_NUM_SW_LIMIT > 32) + else if (id < 64) + map->m1 |= BIT(id-32); +#endif +#if (MACID_NUM_SW_LIMIT > 64) + else if (id < 96) + map->m2 |= BIT(id-64); +#endif +#if (MACID_NUM_SW_LIMIT > 96) + else if (id < 128) + map->m3 |= BIT(id-96); +#endif + else + rtw_warn_on(1); +} + +inline void rtw_macid_map_clr(struct macid_bmp *map, u8 id) +{ + if (id < 32) + map->m0 &= ~BIT(id); +#if (MACID_NUM_SW_LIMIT > 32) + else if (id < 64) + map->m1 &= ~BIT(id-32); +#endif +#if (MACID_NUM_SW_LIMIT > 64) + else if (id < 96) + map->m2 &= ~BIT(id-64); +#endif +#if (MACID_NUM_SW_LIMIT > 96) + else if (id < 128) + map->m3 &= ~BIT(id-96); +#endif + else + rtw_warn_on(1); +} + +inline bool rtw_macid_is_used(struct macid_ctl_t *macid_ctl, u8 id) +{ + return rtw_macid_is_set(&macid_ctl->used, id); +} + +inline bool rtw_macid_is_bmc(struct macid_ctl_t *macid_ctl, u8 id) +{ + return rtw_macid_is_set(&macid_ctl->bmc, id); +} + +inline s8 rtw_macid_get_if_g(struct macid_ctl_t *macid_ctl, u8 id) +{ + int i; + +#ifdef CONFIG_SHARED_BMC_MACID + if (rtw_macid_is_bmc(macid_ctl,id)) + return -1; +#endif + + for (i=0;iif_g[i], id)) + return i; + } + return -1; +} + +inline s8 rtw_macid_get_ch_g(struct macid_ctl_t *macid_ctl, u8 id) +{ + int i; + + for (i=0;i<2;i++) { + if (rtw_macid_is_set(&macid_ctl->ch_g[i], id)) + return i; + } + return -1; +} + void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta) { int i; - _irqL irqL; + _irqL irqL; u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; - struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); - + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + struct macid_bmp *used_map = &macid_ctl->used; + //static u8 last_id = 0; /* for testing */ + u8 last_id = 0; - if(_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN)) + if (_rtw_memcmp(psta->hwaddr, myid(&padapter->eeprompriv), ETH_ALEN)) { + psta->mac_id = macid_ctl->num; return; + } - if(_rtw_memcmp(psta->hwaddr, myid(&padapter->eeprompriv), ETH_ALEN)) - { - psta->mac_id = NUM_STA; - return; +#ifdef CONFIG_SHARED_BMC_MACID + if(_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN)) { + /* use shared broadcast & multicast macid 1 */ + _enter_critical_bh(&macid_ctl->lock, &irqL); + rtw_macid_map_set(used_map, 1); + rtw_macid_map_set(&macid_ctl->bmc, 1); + for (i=0;iif_g[padapter->iface_id], 1); + /* TODO ch_g? */ + _exit_critical_bh(&macid_ctl->lock, &irqL); + i = 1; + goto assigned; } +#endif - _enter_critical_bh(&pdvobj->lock, &irqL); - for(i=0; imacid[i] == _FALSE) - { - pdvobj->macid[i] = _TRUE; + _enter_critical_bh(&macid_ctl->lock, &irqL); + + for (i=last_id;inum;i++) { + #ifdef CONFIG_SHARED_BMC_MACID + if (i == 1) + continue; + #endif + if (!rtw_macid_is_used(macid_ctl, i)) break; - } } - _exit_critical_bh(&pdvobj->lock, &irqL); - if( i > (NUM_STA-1)) - { - psta->mac_id = NUM_STA; - DBG_871X(" no room for more MACIDs\n"); + if (i < macid_ctl->num) { + + rtw_macid_map_set(used_map, i); + + if(_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN)) + rtw_macid_map_set(&macid_ctl->bmc, i); + + rtw_macid_map_set(&macid_ctl->if_g[padapter->iface_id], i); + + /* TODO ch_g? */ + + last_id++; + last_id %= macid_ctl->num; } - else - { - psta->mac_id = i; - DBG_871X("%s = %d\n", __FUNCTION__, psta->mac_id); + + _exit_critical_bh(&macid_ctl->lock, &irqL); + + if (i >= macid_ctl->num) { + psta->mac_id = macid_ctl->num; + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" no available macid\n" + , FUNC_ADPT_ARG(padapter), padapter->iface_id+1, MAC_ARG(psta->hwaddr)); + rtw_warn_on(1); + goto exit; + } else { + goto assigned; } +assigned: + psta->mac_id = i; + DBG_871X(FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" macid:%u\n" + , FUNC_ADPT_ARG(padapter), padapter->iface_id+1, MAC_ARG(psta->hwaddr), psta->mac_id); + +exit: + return; } void rtw_release_macid(_adapter *padapter, struct sta_info *psta) { - int i; - _irqL irqL; + _irqL irqL; u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; - struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + if(_rtw_memcmp(psta->hwaddr, myid(&padapter->eeprompriv), ETH_ALEN)) + return; +#ifdef CONFIG_SHARED_BMC_MACID if(_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN)) return; - if(_rtw_memcmp(psta->hwaddr, myid(&padapter->eeprompriv), ETH_ALEN)) - { + if (psta->mac_id == 1) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" with macid:%u\n" + , FUNC_ADPT_ARG(padapter), padapter->iface_id+1, MAC_ARG(psta->hwaddr), psta->mac_id); + rtw_warn_on(1); return; } +#endif - _enter_critical_bh(&pdvobj->lock, &irqL); - if(psta->mac_idmac_id !=1 ) - { - if(pdvobj->macid[psta->mac_id] == _TRUE) - { - DBG_871X("%s = %d\n", __FUNCTION__, psta->mac_id); - pdvobj->macid[psta->mac_id] = _FALSE; - psta->mac_id = NUM_STA; + _enter_critical_bh(&macid_ctl->lock, &irqL); + + if (psta->mac_id < macid_ctl->num) { + int i; + + if (!rtw_macid_is_used(macid_ctl, psta->mac_id)) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" macid:%u not used\n" + , FUNC_ADPT_ARG(padapter), padapter->iface_id+1, MAC_ARG(psta->hwaddr), psta->mac_id); + rtw_warn_on(1); } + rtw_macid_map_clr(&macid_ctl->used, psta->mac_id); + rtw_macid_map_clr(&macid_ctl->bmc, psta->mac_id); + for (i=0;iif_g[i], psta->mac_id); + for (i=0;i<2;i++) + rtw_macid_map_clr(&macid_ctl->ch_g[i], psta->mac_id); } - _exit_critical_bh(&pdvobj->lock, &irqL); + _exit_critical_bh(&macid_ctl->lock, &irqL); + + psta->mac_id = macid_ctl->num; } + //For 8188E RA u8 rtw_search_max_mac_id(_adapter *padapter) { u8 max_mac_id=0; - struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); int i; - _irqL irqL; - _enter_critical_bh(&pdvobj->lock, &irqL); - for(i=(NUM_STA-1); i>=0 ; i--) - { - if(pdvobj->macid[i] == _TRUE) - { + _irqL irqL; + + _enter_critical_bh(&macid_ctl->lock, &irqL); + for(i=(macid_ctl->num-1); i>0 ; i--) { + if (!rtw_macid_is_used(macid_ctl, i)) break; - } } + _exit_critical_bh(&macid_ctl->lock, &irqL); max_mac_id = i; - _exit_critical_bh(&pdvobj->lock, &irqL); return max_mac_id; - } +inline void rtw_macid_ctl_init(struct macid_ctl_t *macid_ctl) +{ + _rtw_spinlock_init(&macid_ctl->lock); +} + +inline void rtw_macid_ctl_deinit(struct macid_ctl_t *macid_ctl) +{ + _rtw_spinlock_free(&macid_ctl->lock); +} + #if 0 unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame) { @@ -3472,152 +3869,7 @@ func_exit: return res; } -/* - * Description: - * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload - * contant. - * - * Input: - * adapter: adapter pointer. - * page_num: The max. page number that user want to dump. - * page_size: page size of each page. eg. 128 bytes, 256 bytes. - */ -void dump_TX_FIFO(_adapter* padapter, u8 page_num, u16 page_size){ - - int i; - u8 val = 0; - u8 base = 0; - u32 addr = 0; - u32 count = (page_size / 8); - - if (page_num <= 0) { - DBG_871X("!!%s: incorrect input page_num paramter!\n", __func__); - return; - } - - if (page_size < 128 || page_size > 256) { - DBG_871X("!!%s: incorrect input page_size paramter!\n", __func__); - return; - } - - DBG_871X("+%s+\n", __func__); - val = rtw_read8(padapter, 0x106); - rtw_write8(padapter, 0x106, 0x69); - DBG_871X("0x106: 0x%02x\n", val); - base = rtw_read8(padapter, 0x209); - DBG_871X("0x209: 0x%02x\n", base); - - addr = ((base) * page_size)/8; - for (i = 0 ; i < page_num * count ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } -} - -#ifdef CONFIG_GPIO_API -int rtw_get_gpio(struct net_device *netdev, int gpio_num) -{ - u8 value; - u8 direction; - _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); - struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); - - rtw_ps_deny(adapter, PS_DENY_IOCTL); - - DBG_871X("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate); - LeaveAllPowerSaveModeDirect(adapter); - - /* Read GPIO Direction */ - direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num; - - /* According the direction to read register value */ - if( direction ) - value = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1)& BIT(gpio_num)) >> gpio_num; - else - value = (rtw_read8(adapter, REG_GPIO_PIN_CTRL)& BIT(gpio_num)) >> gpio_num; - - rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); - DBG_871X("%s direction=%d value=%d\n",__FUNCTION__,direction,value); - - return value; -} -EXPORT_SYMBOL(rtw_get_gpio); - -int rtw_set_gpio_output_value(struct net_device *netdev, int gpio_num, BOOLEAN isHigh) -{ - u8 direction = 0; - u8 res = -1; - _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); - - /* Check GPIO is 4~7 */ - if( gpio_num > 7 || gpio_num < 4) - { - DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__); - return -1; - } - - rtw_ps_deny(adapter, PS_DENY_IOCTL); - LeaveAllPowerSaveModeDirect(adapter); - - /* Read GPIO direction */ - direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num; - - /* If GPIO is output direction, setting value. */ - if( direction ) - { - if(isHigh) - rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) | BIT(gpio_num)); - else - rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(gpio_num)); - - DBG_871X("%s Set gpio %x[%d]=%d\n",__FUNCTION__,REG_GPIO_PIN_CTRL+1,gpio_num,isHigh ); - res = 0; - } - else - { - DBG_871X("%s The gpio is input,not be set!\n",__FUNCTION__); - res = -1; - } - - rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); - return res; -} -EXPORT_SYMBOL(rtw_set_gpio_output_value); - -int rtw_config_gpio(struct net_device *netdev, int gpio_num, BOOLEAN isOutput) -{ - _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); - - if( gpio_num > 7 || gpio_num < 4) - { - DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__); - return -1; - } - - DBG_871X("%s gpio_num =%d direction=%d\n",__FUNCTION__,gpio_num,isOutput); - - rtw_ps_deny(adapter, PS_DENY_IOCTL); - - LeaveAllPowerSaveModeDirect(adapter); - - if( isOutput ) - { - rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) | BIT(gpio_num)); - } - else - { - rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(gpio_num)); - } - - rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); - - return 0; -} -EXPORT_SYMBOL(rtw_config_gpio); -#endif #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip) @@ -3824,9 +4076,13 @@ int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t* ssid, nlo_info->fast_scan_period = pno_time; nlo_info->ssid_num = num & BIT_LEN_MASK_32(8); + nlo_info->hidden_ssid_num = num & BIT_LEN_MASK_32(8); nlo_info->slow_scan_period = (pno_time * 2); nlo_info->fast_scan_iterations = 5; + if (nlo_info->hidden_ssid_num > 8) + nlo_info->hidden_ssid_num = 8; + //TODO: channel list and probe index is all empty. for (i = 0 ; i < num ; i++) { nlo_info->ssid_length[i] @@ -3876,6 +4132,7 @@ int rtw_dev_ssid_list_set(struct pno_ssid_list *pno_ssid_list, for (i = 0 ; i < num ; i++) { _rtw_memcpy(&pno_ssid_list->node[i].SSID, ssid[i].SSID, ssid[i].SSID_len); + pno_ssid_list->node[i].SSID_len = ssid[i].SSID_len; } return 0; } @@ -3966,15 +4223,15 @@ int rtw_dev_pno_set(struct net_device *net, pno_ssid_t* ssid, int num, failing: if (pwrctl->pnlo_info) { - rtw_mfree(pwrctl->pnlo_info, sizeof(pno_nlo_info_t)); + rtw_mfree((u8 *)pwrctl->pnlo_info, sizeof(pno_nlo_info_t)); pwrctl->pnlo_info = NULL; } if (pwrctl->pno_ssid_list) { - rtw_mfree(pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t)); + rtw_mfree((u8 *)pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t)); pwrctl->pno_ssid_list = NULL; } if (pwrctl->pscan_info) { - rtw_mfree(pwrctl->pscan_info, sizeof(pno_scan_info_t)); + rtw_mfree((u8 *)pwrctl->pscan_info, sizeof(pno_scan_info_t)); pwrctl->pscan_info = NULL; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_xmit.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_xmit.c index 79c3b6185ced..581113925c23 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_xmit.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/core/rtw_xmit.c @@ -448,7 +448,6 @@ u8 query_ra_short_GI(struct sta_info *psta) if (psta->vhtpriv.vht_option) { sgi_80m= psta->vhtpriv.sgi_80m; } - else #endif //CONFIG_80211AC_VHT { sgi_20m = psta->htpriv.sgi_20m; @@ -964,6 +963,18 @@ exit: #endif //CONFIG_TDLS +//get non-qos hw_ssn control register,mapping to REG_HW_SEQ0,1,2,3 +inline u8 rtw_get_hwseq_no(_adapter *padapter) +{ + u8 hwseq_num = 0; +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type == SECONDARY_ADAPTER) + hwseq_num = 1; + //else + // hwseq_num = 2; +#endif //CONFIG_CONCURRENT_MODE + return hwseq_num; +} static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib) { uint i; @@ -974,8 +985,9 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr sint bmcast; struct sta_priv *pstapriv = &padapter->stapriv; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct qos_priv *pqospriv= &pmlmepriv->qospriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; sint res = _SUCCESS; _func_enter_; @@ -1181,7 +1193,7 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr } //pattrib->priority = 5; //force to used VI queue, for testing - + pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no; rtw_set_tx_chksum_offload(pkt, pattrib); exit: @@ -2242,7 +2254,7 @@ _func_enter_; int frame_body_len; u8 mic[16]; - _rtw_memset(MME, 0, 18); + _rtw_memset(MME, 0, _MME_IE_LENGTH_); //other types doesn't need the BIP if(GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC) @@ -3001,7 +3013,7 @@ _func_enter_; else if(pxmitframe->ext_tag == 1) queue = &pxmitpriv->free_xframe_ext_queue; else - {} + rtw_warn_on(1); _enter_critical_bh(&queue->lock, &irqL); @@ -3108,7 +3120,7 @@ static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, str break; - pxmitframe = NULL; + //pxmitframe = NULL; } @@ -4011,7 +4023,7 @@ sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *p //pattrib->triggered=0; if (bmcst && xmitframe_hiq_filter(pxmitframe) == _TRUE) - pattrib->qsel = 0x11;//HIQ + pattrib->qsel = QSLT_HIGH;//HIQ return ret; } @@ -4023,7 +4035,7 @@ sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *p if(pstapriv->sta_dz_bitmap)//if anyone sta is in ps mode { - //pattrib->qsel = 0x11;//HIQ + //pattrib->qsel = QSLT_HIGH;//HIQ rtw_list_delete(&pxmitframe->list); @@ -4042,7 +4054,10 @@ sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *p //DBG_871X("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); if (update_tim == _TRUE) { - update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + if (is_broadcast_mac_addr(pattrib->ra)) + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer BC"); + else + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer MC"); } else { chk_bmc_sleepq_cmd(padapter); } @@ -4115,7 +4130,7 @@ sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *p { //DBG_871X("sleepq_len==1, update BCNTIM\n"); //upate BCN for TIM IE - update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer UC"); } } @@ -4422,8 +4437,12 @@ _exit: if(update_mask) { //update_BCNTIM(padapter); - //printk("%s => call update_beacon\n",__FUNCTION__); - update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + if ((update_mask & (BIT(0)|BIT(1))) == (BIT(0)|BIT(1))) + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC&BMC"); + else if ((update_mask & BIT(1)) == BIT(1)) + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear BMC"); + else + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC"); } } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/HalPwrSeqCmd.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/HalPwrSeqCmd.c index 425fbefc8b68..972a3d893fa6 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/HalPwrSeqCmd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/HalPwrSeqCmd.c @@ -147,7 +147,7 @@ u8 HalPwrSeqCmdParsing( rtw_udelay_os(10); if (pollingCount++ > maxPollingCnt) { - DBG_871X("Fail to polling Offset[%#x]=%02x\n", offset, value); + DBG_871X_LEVEL(_drv_always_, "HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value); return _FALSE; } } while (!bPollingBit); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.c index 9f691416a493..6e9454ca5cca 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.c @@ -1774,11 +1774,6 @@ EXhalbtc8188c2ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); CL_PRINTF(cliBuf); @@ -1797,34 +1792,12 @@ EXhalbtc8188c2ant_DisplayCoexInfo( ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); if(pStackInfo->bProfileNotified) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192d2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192d2Ant.c index 239da74f5252..cb60379c9a86 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192d2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192d2Ant.c @@ -1780,11 +1780,6 @@ EXhalbtc8192d2ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); CL_PRINTF(cliBuf); @@ -1803,34 +1798,12 @@ EXhalbtc8192d2ant_DisplayCoexInfo( ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); if(pStackInfo->bProfileNotified) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e1Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e1Ant.c index 36a48d082138..12dfe4b210eb 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e1Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e1Ant.c @@ -2519,11 +2519,6 @@ EXhalbtc8192e1ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; u4Byte fwVer=0, btPatchVer=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); @@ -2558,40 +2553,19 @@ EXhalbtc8192e1ant_DisplayCoexInfo( GLCoexVerDate8192e1Ant, GLCoexVer8192e1Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); - CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": ( (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), @@ -2620,17 +2594,6 @@ EXhalbtc8192e1ant_DisplayCoexInfo( CL_PRINTF(cliBuf); } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s, (0x%x/0x%x)", "PS state, IPS/LPS, (lps/rpwm)", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF")), - pBtCoexist->btInfo.lpsVal, - pBtCoexist->btInfo.rpwmVal); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "SS Type", \ - pCoexDm->curSsType); - CL_PRINTF(cliBuf); if(!pBtCoexist->bManualControl) { @@ -2638,10 +2601,6 @@ EXhalbtc8192e1ant_DisplayCoexInfo( CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============"); CL_PRINTF(cliBuf); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d(0x%x) ", "SM[SwDacSwing(lvl)]", \ - pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); - CL_PRINTF(cliBuf); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %d ", "DelBA/ BtCtrlAgg/ AggSize", \ (pBtCoexist->btInfo.bRejectAggPkt? "Yes":"No"), (pBtCoexist->btInfo.bBtCtrlAggBufSize? "Yes":"No"), pBtCoexist->btInfo.aggBufSize); @@ -2665,8 +2624,8 @@ EXhalbtc8192e1ant_DisplayCoexInfo( pCoexDm->errorCondition); CL_PRINTF(cliBuf); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwrLvl/ IgnWlanAct", \ - pCoexDm->curBtDecPwrLvl, pCoexDm->bCurIgnoreWlanAct); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IgnWlanAct", \ + pCoexDm->bCurIgnoreWlanAct); CL_PRINTF(cliBuf); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e2Ant.c index b17ee766e581..8bde294c93f2 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8192e2Ant.c @@ -1697,7 +1697,8 @@ halbtc8192e2ant_SetSwitchSsType( pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xd04, 0x1); pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x90c, 0x81111111); // switch cck patch - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xe77, 0x4, 0x1); + //Jenyu suggest to remove 0xe77 this line for tx issue + //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xe77, 0x4, 0x1); //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xa07, 0x81); mimoPs=BTC_MIMO_PS_STATIC; } @@ -1707,7 +1708,8 @@ halbtc8192e2ant_SetSwitchSsType( pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xc04, 0x33); pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xd04, 0x3); pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x90c, 0x81121313); - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xe77, 0x4, 0x0); + //Jenyu suggest to remove 0xe77 this line for tx issue + //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xe77, 0x4, 0x0); //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xa07, 0x41); mimoPs=BTC_MIMO_PS_DYNAMIC; } @@ -3827,11 +3829,7 @@ EXhalbtc8192e2ant_DisplayCoexInfo( u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u2Byte u2Tmp[4]; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir, faOfdm, faCck; - u1Byte wifiDot11Chnl, wifiHsChnl; + u4Byte faOfdm, faCck; u4Byte fwVer=0, btPatchVer=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); @@ -3859,39 +3857,17 @@ EXhalbtc8192e2ant_DisplayCoexInfo( GLCoexVerDate8192e2Ant, GLCoexVer8192e2Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsMode(HsChnl)", \ - wifiDot11Chnl, bBtHsOn, wifiHsChnl); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ @@ -3923,12 +3899,6 @@ EXhalbtc8192e2ant_DisplayCoexInfo( } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", "PS state, IPS/LPS", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF"))); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "SS Type", \ pCoexDm->curSsType); CL_PRINTF(cliBuf); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a1Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a1Ant.c index 8cd3d15b3146..8ea08e87d3de 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a1Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a1Ant.c @@ -1068,11 +1068,6 @@ EXhalbtc8723a1ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); CL_PRINTF(cliBuf); @@ -1091,39 +1086,17 @@ EXhalbtc8723a1ant_DisplayCoexInfo( ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ @@ -1251,12 +1224,6 @@ EXhalbtc8723a1ant_DisplayCoexInfo( pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); CL_PRINTF(cliBuf); - // Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang - u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x41b); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (mgntQ hang chk == 0xf)", \ - u1Tmp[0]); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a2Ant.c index 3e115864cd21..ffe117596f5b 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723a2Ant.c @@ -3429,11 +3429,6 @@ EXhalbtc8723a2ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); CL_PRINTF(cliBuf); @@ -3452,39 +3447,17 @@ EXhalbtc8723a2ant_DisplayCoexInfo( ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ @@ -3615,12 +3588,6 @@ EXhalbtc8723a2ant_DisplayCoexInfo( pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); CL_PRINTF(cliBuf); - // Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang - u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x41b); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (mgntQ hang chk == 0xf)", \ - u1Tmp[0]); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.c index b351f6c87a20..bada4139b1f2 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.c @@ -20,6 +20,9 @@ static COEX_DM_8723B_1ANT GLCoexDm8723b1Ant; static PCOEX_DM_8723B_1ANT pCoexDm=&GLCoexDm8723b1Ant; static COEX_STA_8723B_1ANT GLCoexSta8723b1Ant; static PCOEX_STA_8723B_1ANT pCoexSta=&GLCoexSta8723b1Ant; +static PSDSCAN_STA_8723B_1ANT GLPsdScan8723b1Ant; +static PPSDSCAN_STA_8723B_1ANT pPsdScan = &GLPsdScan8723b1Ant; + const char *const GLBtInfoSrc8723b1Ant[]={ "BT Info[wifi fw]", @@ -27,8 +30,8 @@ const char *const GLBtInfoSrc8723b1Ant[]={ "BT Info[bt auto report]", }; -u4Byte GLCoexVerDate8723b1Ant=20140702; -u4Byte GLCoexVer8723b1Ant=0x51; +u4Byte GLCoexVerDate8723b1Ant=20140929; +u4Byte GLCoexVer8723b1Ant=0x54; //============================================================ // local function proto type if needed @@ -442,6 +445,15 @@ halbtc8723b1ant_MonitorBtCtr( //to avoid 0x76e[3] = 1 (WLAN_Act control by PTA) during IPS //if (! (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e) & 0x8) ) + if (pCoexSta->bUnderIps) + { + //pCoexSta->highPriorityTx = 65535; + //pCoexSta->highPriorityRx = 65535; + //pCoexSta->lowPriorityTx = 65535; + //pCoexSta->lowPriorityRx = 65535; + //return; + } + regHPTxRx = 0x770; regLPTxRx = 0x774; @@ -571,6 +583,9 @@ halbtc8723b1ant_MonitorWiFiCtr( pCoexSta->bCCKLock = TRUE; } + if (pCoexSta->bCCKLock) + pCoexSta->bCCKEverLock = TRUE; + pCoexSta->bPreCCKLock = pCoexSta->bCCKLock; @@ -627,6 +642,7 @@ halbtc8723b1ant_UpdateBtLinkInfo( pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; pBtLinkInfo->bPanExist = pCoexSta->bPanExist; pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + pBtLinkInfo->bBtHiPriLinkExist = pCoexSta->bBtHiPriLinkExist; // work around for HS mode. if(bBtHsOn) @@ -1057,10 +1073,13 @@ halbtc8723b1ant_CoexTableWithType( halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); break; case 4: - halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaa5a5a, 0xffffff, 0x3); + if ((pCoexSta->nScanAPNum <= 5) || ( pCoexSta->bCCKEverLock) ) + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3); + else + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaa5a5a, 0xffffff, 0x3); break; case 5: - halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0xaa5a5a5a, 0xffffff, 0x3); + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0xaaaa5a5a, 0xffffff, 0x3); break; case 6: halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3); @@ -1181,6 +1200,7 @@ VOID halbtc8723b1ant_SetAntPath( IN PBTC_COEXIST pBtCoexist, IN u1Byte antPosType, + IN BOOLEAN bForceExec, IN BOOLEAN bInitHwCfg, IN BOOLEAN bWifiOff ) @@ -1192,6 +1212,8 @@ halbtc8723b1ant_SetAntPath( BOOLEAN bIsInMpMode = FALSE; u1Byte H2C_Parameter[2] ={0}, u1Tmp = 0; + pCoexDm->curAntPosType = antPosType; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_EXT_SWITCH, &bPgExtSwitch); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); // [31:16]=fw ver, [15:0]=fw sub ver @@ -1201,7 +1223,8 @@ halbtc8723b1ant_SetAntPath( if(bInitHwCfg) { pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); //WiFi TRx Mask on - pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); //BT TRx Mask on + //remove due to interrupt is disabled that polling c2h will fail and delay 100ms. + //pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); //BT TRx Mask on if(fwVer >= 0x180000) { @@ -1217,7 +1240,7 @@ halbtc8723b1ant_SetAntPath( //set wlan_act control by PTA pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); //BT select s0/s1 is controlled by WiFi + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x0); //BT select s0/s1 is controlled by BT pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x39, 0x8, 0x1); pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x974, 0xff); @@ -1291,6 +1314,8 @@ halbtc8723b1ant_SetAntPath( //set wlan_act control by PTA pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); } + + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); //BT select s0/s1 is controlled by WiFi } if(bUseExtSwitch) @@ -1321,31 +1346,32 @@ halbtc8723b1ant_SetAntPath( } } - - // ext switch setting - switch(antPosType) + if(bForceExec || (pCoexDm->curAntPosType != pCoexDm->preAntPosType)) { - case BTC_ANT_PATH_WIFI: - if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); - else - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); - break; - case BTC_ANT_PATH_BT: - if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); - else - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); - break; - default: - case BTC_ANT_PATH_PTA: - if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); - else - pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); - break; + // ext switch setting + switch(antPosType) + { + case BTC_ANT_PATH_WIFI: + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); + break; + case BTC_ANT_PATH_BT: + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); + break; + default: + case BTC_ANT_PATH_PTA: + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); + break; + } } - } else { @@ -1378,31 +1404,35 @@ halbtc8723b1ant_SetAntPath( } } - - // internal switch setting - switch(antPosType) + if(bForceExec || (pCoexDm->curAntPosType != pCoexDm->preAntPosType)) { - case BTC_ANT_PATH_WIFI: - if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); - else - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280); - break; - case BTC_ANT_PATH_BT: - if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280); - else - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); - break; - default: - case BTC_ANT_PATH_PTA: - if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x200); - else - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x80); - break; + // internal switch setting + switch(antPosType) + { + case BTC_ANT_PATH_WIFI: + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); + else + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280); + break; + case BTC_ANT_PATH_BT: + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280); + else + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); + break; + default: + case BTC_ANT_PATH_PTA: + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x200); + else + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x80); + break; + } } } + + pCoexDm->preAntPosType = pCoexDm->curAntPosType; } VOID @@ -1513,7 +1543,7 @@ halbtc8723b1ant_PsTdma( if (bWifiBusy != bPreWifiBusy) { - bForceExec = TRUE; + bForceExec = TRUE; bPreWifiBusy = bWifiBusy; } @@ -1536,32 +1566,33 @@ halbtc8723b1ant_PsTdma( } if (pCoexSta->nScanAPNum <= 5) - nWiFiDurationAdjust = 2; + nWiFiDurationAdjust = 5; + //nWiFiDurationAdjust = 2; else if (pCoexSta->nScanAPNum >= 40) - nWiFiDurationAdjust = -15; + nWiFiDurationAdjust = -15; else if (pCoexSta->nScanAPNum >= 20) - nWiFiDurationAdjust = -10; + nWiFiDurationAdjust = -10; - if (!pCoexSta->bForceLpsOn) //only for A2DP-only case 1/2/9/11 + if (!pCoexSta->bForceLpsOn) //only for A2DP-only case 1/2/9/11 while wifi noisy threshold > 30 { psTdmaByte0Val = 0x61; //no null-pkt psTdmaByte3Val = 0x11; // no tx-pause at BT-slot psTdmaByte4Val = 0x10; // 0x778 = d/1 toggle } - if ( (type == 3) || (type == 13) || (type == 14) ) + if ( (type == 3) || (type == 13) || (type == 14) ) { psTdmaByte4Val = psTdmaByte4Val & 0xbf; //no dynamic slot for multi-profile - + if (!bWifiBusy) psTdmaByte4Val = psTdmaByte4Val | 0x1; //0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) - } - + } + if (pBtLinkInfo->bSlaveRole == TRUE) psTdmaByte4Val = psTdmaByte4Val | 0x1; //0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) - + if(bTurnOn) - { + { switch(type) { default: @@ -1684,44 +1715,35 @@ halbtc8723b1ant_PsTdma( case 8: //PTA Control halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); //halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_PTA, BTC_WIFI_STAT_NORMAL); - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FALSE, FALSE); + //halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FALSE, FALSE); break; case 0: default: //Software control, Antenna at BT side halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); //halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL); - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, FALSE); + //halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, FALSE); break; +#if 0 case 9: //Software control, Antenna at WiFi side halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); //halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_WIFI, BTC_WIFI_STAT_NORMAL); halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, FALSE, FALSE); break; +#endif } } rssiAdjustVal =0; pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssiAdjustVal); + BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", - pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67))); + pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67))); // update pre state pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; pCoexDm->prePsTdma = pCoexDm->curPsTdma; } -VOID -halbtc8723b1ant_CoexAllOff( - IN PBTC_COEXIST pBtCoexist - ) -{ - // sw all off - halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); - - // hw all off - halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); -} - BOOLEAN halbtc8723b1ant_IsCommonAction( IN PBTC_COEXIST pBtCoexist @@ -2020,7 +2042,7 @@ halbtc8723b1ant_PsTdmaCheckForPowerSaveState( else { // will leave LPS state, turn off psTdma first - halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); } } else // NO PS state @@ -2028,7 +2050,7 @@ halbtc8723b1ant_PsTdmaCheckForPowerSaveState( if(bNewPsState) { // will enter LPS state, turn off psTdma first - halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); } else { @@ -2082,7 +2104,8 @@ halbtc8723b1ant_ActionWifiOnly( ) { halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); - halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 9); + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); } VOID @@ -2248,6 +2271,18 @@ halbtc8723b1ant_ActionHidA2dp( // Non-Software Coex Mechanism start // //============================================= +VOID +halbtc8723b1ant_ActionBtWhckTest( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + VOID halbtc8723b1ant_ActionWifiMultiPort( IN PBTC_COEXIST pBtCoexist @@ -2256,6 +2291,7 @@ halbtc8723b1ant_ActionWifiMultiPort( halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); } @@ -2285,7 +2321,7 @@ halbtc8723b1ant_ActionBtInquiry( { halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); - + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); } else if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist) ) @@ -2299,16 +2335,24 @@ halbtc8723b1ant_ActionBtInquiry( else if ( (pBtLinkInfo->bPanExist) || (bWifiBusy) ) { halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); - halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + + //for BT inquiry/page fail after S4 resume + //halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); } else { halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); - + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + + + //halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + //halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); } } @@ -2418,6 +2462,7 @@ halbtc8723b1ant_ActionWifiNotConnected( // tdma and coex table halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); } @@ -2459,6 +2504,7 @@ halbtc8723b1ant_ActionWifiNotConnectedScan( { //Bryant Add halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); } } @@ -2476,16 +2522,17 @@ halbtc8723b1ant_ActionWifiNotConnectedAssoAuth( if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist) ) { halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); - halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); } else if (pBtLinkInfo->bPanExist) { halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); - halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); } else { halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 2); } } @@ -2528,6 +2575,7 @@ halbtc8723b1ant_ActionWifiConnectedScan( { //Bryant Add halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); } } @@ -2555,6 +2603,7 @@ halbtc8723b1ant_ActionWifiConnectedSpecialPacket( else { halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); } } @@ -2639,7 +2688,7 @@ halbtc8723b1ant_ActionWifiConnected( else { halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); - + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); if ( (pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60 ) halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); else @@ -2662,7 +2711,7 @@ halbtc8723b1ant_ActionWifiConnected( else { halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); - + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); if ( (pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60 ) halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); else @@ -2773,6 +2822,13 @@ halbtc8723b1ant_RunCoexistMechanism( return; } + if(pCoexSta->bBtWhckTest) + { + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BT is under WHCK TEST!!!\n")); + halbtc8723b1ant_ActionBtWhckTest(pBtCoexist); + return; + } + if( (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) @@ -2797,7 +2853,7 @@ halbtc8723b1ant_RunCoexistMechanism( } else { - halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); bMiracastPlusBt = FALSE; } pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); @@ -2825,15 +2881,21 @@ halbtc8723b1ant_RunCoexistMechanism( { halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + if(pBtLinkInfo->bScoExist)//if (pBtLinkInfo->bBtHiPriLinkExist) + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x5); + else + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + /* if(pBtLinkInfo->bScoExist) halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x5); else { if (BTC_WIFI_BW_HT40==wifiBw) - halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x10); - else - halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x10); + else + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); } + */ halbtc8723b1ant_SwMechanism(pBtCoexist, TRUE); halbtc8723b1ant_RunSwCoexistMechanism(pBtCoexist); //just print debug message @@ -2888,6 +2950,59 @@ halbtc8723b1ant_RunCoexistMechanism( } } +u4Byte +halbtc8723b1ant_Log2Base( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val + + ) +{ + u1Byte i,j; + u4Byte tmp, tmp2, val_integerdB=0, tindex, shiftcount=0; + u4Byte result,val_fractiondB=0,Table_fraction[21]= {0,432, 332, 274, 232, 200, + 174, 151,132,115,100,86,74,62,51,42, + 32,23,15,7,0}; + + if (val == 0) + return 0; + + tmp = val; + + while(1) + { + if (tmp == 1) + break; + else + { + tmp = (tmp >> 1); + shiftcount++; + } + } + + + val_integerdB = shiftcount+1; + + tmp2=1; + for (j=1; j<= val_integerdB;j++) + tmp2 = tmp2*2; + + tmp = (val*100) /tmp2; + tindex = tmp/5; + + if (tindex > 20) + tindex = 20; + + val_fractiondB = Table_fraction[tindex]; + + result = val_integerdB*100 - val_fractiondB; + + return (result); + + +} + + + VOID halbtc8723b1ant_InitCoexDm( IN PBTC_COEXIST pBtCoexist @@ -2899,7 +3014,7 @@ halbtc8723b1ant_InitCoexDm( halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); //halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); - halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + //halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); pCoexSta->popEventCnt = 0; } @@ -2918,6 +3033,8 @@ halbtc8723b1ant_InitHwConfig( u1Byte H2C_Parameter[2] ={0}; BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], 1Ant Init HW Config!!\n")); + + pPsdScan->bIsAntDetEnable = FALSE; #if 0//move to BTC_MEDIA_CONNECT if(bBackUp) { @@ -2940,23 +3057,19 @@ halbtc8723b1ant_InitHwConfig( //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); //BT select s0/s1 is controlled by WiFi + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + //Antenna config -#if 1 if(bWifiOnly) - { - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, TRUE, FALSE); - halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 9); - } + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, FORCE_EXEC, TRUE, FALSE); else - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, TRUE, FALSE); -#endif - + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, TRUE, FALSE); #if 0 if(bWifiOnly) { halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_WIFI, BTC_WIFI_STAT_INIT); - halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 9); + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); } else halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_INIT); @@ -2975,16 +3088,508 @@ halbtc8723b1ant_InitHwConfig( u4Tmp, u1Tmpa, u1Tmpb)); } -/* VOID -halbtc8723b1ant_WifiOffHwCfg( +halbtc8723b1ant_ShowPSDData( IN PBTC_COEXIST pBtCoexist ) { - // set wlan_act to low - //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + pu1Byte cliBuf=pBtCoexist->cliBuf; + u4Byte nDeltaFreqPerPoint; + u4Byte freq,freq1,freq2,n=0,i=0, j=0, m=0, PsdRep1, PsdRep2; + + DbgPrint("xxxxxxxxxxxxxxxx DisplayAntIsolation()\n"); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n============[Antenna Detection info] (%d/%d)============\n", + pPsdScan->nPSDGenCount, pPsdScan->nPSDGenTotalCount); + CL_PRINTF(cliBuf); + + if (pPsdScan->nPSDGenTotalCount == 0) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n No Data !!\n"); + CL_PRINTF(cliBuf); + return; + } + + if (pPsdScan->nPSDPoint == 0) + nDeltaFreqPerPoint = 0; + else + nDeltaFreqPerPoint = pPsdScan->nPSDBandWidth/pPsdScan->nPSDPoint; + + if (pPsdScan->bIsPSDShowMaxOnly) + { + PsdRep1 = pPsdScan->nPSDMaxValue/100; + PsdRep2 = pPsdScan->nPSDMaxValue - PsdRep1 * 100; + + freq = ((pPsdScan->realcentFreq-20) * 1000000 + pPsdScan->nPSDMaxValuePoint * nDeltaFreqPerPoint); + freq1 = freq/1000000; + freq2 = freq/1000 - freq1 * 1000; + + if (freq2 < 100) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n Freq = %d.0%d MHz", + freq1, freq2); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n Freq = %d.%d MHz", + freq1, freq2); + + if (PsdRep2 < 10) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, ", Value = %d.0%d dB, (%d/%d) \n", + PsdRep1, PsdRep2, pPsdScan->nPSDGenCount, pPsdScan->nPSDGenTotalCount); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, ", Value = %d.%d dB, %d, (%d/%d)\n", + PsdRep1, PsdRep2, pPsdScan->nPSDMaxValue, pPsdScan->nPSDGenCount, pPsdScan->nPSDGenTotalCount); + + CL_PRINTF(cliBuf); + } + else + { + m = pPsdScan->nPSDStartPoint; + n = pPsdScan->nPSDStartPoint; + i = 1; + j = 1; + + while(1) + { + do + { + freq = ((pPsdScan->realcentFreq-20) * 1000000 + m * nDeltaFreqPerPoint); + freq1 = freq/1000000; + freq2 = freq/1000 - freq1 * 1000; + + if (i ==1) + { + if (freq2 == 0) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n Freq%6d.000", freq1); + else if (freq2 < 100) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n Freq%6d.0%2d", freq1,freq2); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n Freq%6d.%3d", freq1,freq2); + } + else if ( (i%8 == 0) || (m == pPsdScan->nPSDStopPoint) ) + { + if (freq2 == 0) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%6d.000\n", freq1); + else if (freq2 < 100) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%6d.0%2d\n", freq1,freq2); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%6d.%3d\n", freq1,freq2); + } + else + { + if (freq2 == 0) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%6d.000", freq1); + else if (freq2 < 100) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%6d.0%2d", freq1,freq2); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%6d.%3d", freq1,freq2); } -*/ + + i++; + m++; + CL_PRINTF(cliBuf); + + }while( (i <= 8) && (m <= pPsdScan->nPSDStopPoint)); + + + do + { + PsdRep1 = pPsdScan->nPSDReport_MaxHold[n]/100; + PsdRep2 = pPsdScan->nPSDReport_MaxHold[n] - PsdRep1 * 100; + + if (j ==1) + { + if (PsdRep2 <10) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n Val %7d.0%d", PsdRep1,PsdRep2); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n Val %7d.%d", PsdRep1,PsdRep2); + } + else if ( (j%8 == 0) || (n == pPsdScan->nPSDStopPoint) ) + { + if (PsdRep2 <10) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%7d.0%d\n", PsdRep1,PsdRep2); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%7d.%d\n", PsdRep1,PsdRep2); + } + else + { + if (PsdRep2 <10) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%7d.0%d", PsdRep1,PsdRep2); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "%7d.%d", PsdRep1,PsdRep2); + } + + j++; + n++; + CL_PRINTF(cliBuf); + + } while( (j <= 8) && (n <= pPsdScan->nPSDStopPoint)); + + if ( (m > pPsdScan->nPSDStopPoint) || (n > pPsdScan->nPSDStopPoint) ) + break; + else + { + i = 1; + j = 1; + } + + } + } + + +} + +u4Byte +halbtc8723b1ant_GetPSDData( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte nPoint + ) +{ + //reg 0x808[9:0]: FFT data x + //reg 0x808[22]: 0-->1 to get 1 FFT data y + //reg 0x8b4[15:0]: FFT data y report + + u4Byte val = 0, psd_report =0; + + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x808); + + val &= 0xffbffc00; + val |= nPoint; + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x808, val); + + val |= 0x00400000; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x808, val); + + + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x8b4); + + psd_report = val & 0x0000ffff; + + return psd_report; +} + + +void +halbtc8723b1ant_SweepPSDPoint( +IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte points, + IN u4Byte avgnum + ) +{ + u4Byte i,val,n,k=0; + u4Byte nPoints=0, psd_report=0; + u4Byte nStartP=0, nStopP=0, nDeltaFreqPerPoint=156250; + u4Byte nPSDCenterFreq=20*10^6, freq,freq1,freq2; + BOOLEAN outloop = FALSE; + u1Byte flag = 0; + u4Byte tmp, PsdRep1, PsdRep2; + + pPsdScan->bIsPSDRunning = TRUE; + + do + { + switch(flag) + { + case 0: //Get PSD parameters + default: + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), centFreq=0x%x, offset=0x%x, span=0x%x\n", + centFreq, offset, span); + + pPsdScan->nPSDBandWidth = 40*1000000; + pPsdScan->nPSDPoint = points; + pPsdScan->nPSDStartBase = points/2; + pPsdScan->nPSDAvgNum = avgnum; + + nPoints = pPsdScan->nPSDPoint; + nDeltaFreqPerPoint = pPsdScan->nPSDBandWidth/pPsdScan->nPSDPoint; + + //PSD point setup + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x808); + val &= 0xffff0fff; + + switch(pPsdScan->nPSDPoint) + { + case 128: + val |= 0x0; + break; + case 256: + default: + val |=0x00004000; + break; + case 512: + val |= 0x00008000; + break; + case 1024: + val |= 0x0000c000; + break; + } + + switch(pPsdScan->nPSDAvgNum) + { + case 1: + val |= 0x0; + break; + case 8: + val |=0x00001000; + break; + case 16: + val |= 0x00002000; + break; + case 32: + default: + val |= 0x00003000; + break; + } + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x808, val); + + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), PSD BW= %d, DeltaFreq=%d\n" + , pPsdScan->nPSDBandWidth, nDeltaFreqPerPoint); + flag = 1; + break; + case 1: //calculate the PSD point index from freq/offset/span + nPSDCenterFreq = pPsdScan->nPSDBandWidth /2 +offset*(1000000); + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), PSD Center Freq = %d\n", (centFreq + offset)); + + nStartP = pPsdScan->nPSDStartBase + (nPSDCenterFreq - span *(1000000)/2) /nDeltaFreqPerPoint; + pPsdScan->nPSDStartPoint = nStartP - pPsdScan->nPSDStartBase; + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), Start PSD Poin Matrix Index = %d\n", pPsdScan->nPSDStartPoint); + + nStopP = pPsdScan->nPSDStartBase + (nPSDCenterFreq + span *(1000000)/2) /nDeltaFreqPerPoint; + pPsdScan->nPSDStopPoint = nStopP - pPsdScan->nPSDStartBase-1; + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), Stop PSD Poin Matrix Index = %d\n",pPsdScan->nPSDStopPoint); + + flag = 2; + break; + case 2: //set RF channel/BW/Mode + + //set 3-wire off + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x88c); + val |= 0x00300000; + pBtCoexist->fBtcWrite4Byte(pBtCoexist,0x88c,val); + + //CCK off + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x800); + val &= 0xfeffffff; + pBtCoexist->fBtcWrite4Byte(pBtCoexist,0x800,val); + + //Set RF channel + if (centFreq == 2484) + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff, 0xe); //WiFi TRx Mask on + else + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff, (centFreq-2412)/5 + 1); //WiFi TRx Mask on + + //Set RF mode = Rx, RF Gain = 0x8a0 + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x0, 0xfffff, 0x308a0); + + //Set TRx mask off + //un-lock TRx Mask setup + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdd, 0x80, 0x1); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdf, 0x1, 0x1); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + flag = 3; + break; + case 3: + memset(pPsdScan->nPSDReport,0, pPsdScan->nPSDPoint*sizeof(u4Byte)); + nStartP = pPsdScan->nPSDStartPoint + pPsdScan->nPSDStartBase; + nStopP = pPsdScan->nPSDStopPoint + pPsdScan->nPSDStartBase + 1; + + i = nStartP; + + while (i < nStopP) + { + if (i >= nPoints) + { + psd_report = halbtc8723b1ant_GetPSDData(pBtCoexist,i-nPoints); + } + else + { + psd_report = halbtc8723b1ant_GetPSDData(pBtCoexist,i); + } + + if (psd_report == 0) + tmp = 0; + else + //tmp = 20*log10((double)psd_report); + //20*log2(x)/log2(10), log2Base return theresult of the psd_report*100 + tmp = 6 * halbtc8723b1ant_Log2Base(pBtCoexist, psd_report); + + + n = i-pPsdScan->nPSDStartBase; + pPsdScan->nPSDReport[n] = tmp; + PsdRep1 = pPsdScan->nPSDReport[n] /100; + PsdRep2 = pPsdScan->nPSDReport[n] - PsdRep1 * 100; + + freq = ((centFreq-20) * 1000000 + n * nDeltaFreqPerPoint); + freq1 = freq/1000000; + freq2 = freq/1000 - freq1 * 1000; + + if (freq2 < 100) + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), i = %d (%d.0%d MHz)", n, freq1, freq2); + else + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), i = %d (%d.%d MHz)", n, freq1, freq2); + + if (PsdRep2 < 10) + DbgPrint(", PSDReport = %d (%d.0%d dB)\n",psd_report, PsdRep1, PsdRep2); + else + DbgPrint(", PSDReport = %d (%d.%d dB)\n",psd_report, PsdRep1,PsdRep2); + + i++; + + k=0; + + //Add Delay between PSD point + while(1) + { + if (k++ > 20000) + break; + } + + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint()==============\n"); + } + + flag = 100; + break; + case 99: //error + + outloop = TRUE; + break; + case 100: //recovery + + //set 3-wire on + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x88c); + val &=0xffcfffff; + pBtCoexist->fBtcWrite4Byte(pBtCoexist,0x88c,val); + + //CCK on + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x800); + val |= 0x01000000; + pBtCoexist->fBtcWrite4Byte(pBtCoexist,0x800,val); + + //PSD off + val = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x808); + val &=0xffbfffff; + pBtCoexist->fBtcWrite4Byte(pBtCoexist,0x808,val); + + //TRx Mask on + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdd, 0x80, 0x0); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdf, 0x1, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); + + outloop = TRUE; + break; + + } + + }while (!outloop); + + + + pPsdScan->bIsPSDRunning = FALSE; + + +} + +VOID +halbtc8723b1ant_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + u4Byte realseconds = 0, i=0, i_max=0, val_max=0, j; + + //Stop Coex DM + pBtCoexist->bStopCoexDm = TRUE; + + //Set Antenna path, switch WiFi to un-certain antenna port + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, FALSE); + + //Mailbox handshake + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x62, 1, 0x0); + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), Set BT LE Tx\n"); + + //sweep PSD + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), \n"); + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), \n"); + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), \n"); + + + //Analysis Data + + do + { + halbtc8723b1ant_SweepPSDPoint(pBtCoexist, centFreq, offset,span, BT_8723B_1ANT_ANTDET_PSD_POINTS, BT_8723B_1ANT_ANTDET_PSD_AVGNUM); + + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), PSDGenCount = %d\n ", pPsdScan->nPSDGenCount); + + if (pPsdScan->nPSDGenCount == 0) + { + memcpy(pPsdScan->nPSDReport_MaxHold, pPsdScan->nPSDReport, BT_8723B_1ANT_ANTDET_PSD_POINTS*sizeof(u4Byte)); + + for (i= pPsdScan->nPSDStartPoint; i<=pPsdScan->nPSDStopPoint; i++) + { + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i = %d, PSDReport = %d dB\n", i, pPsdScan->nPSDReport_MaxHold[i]); + } + } + else + { + for (i= pPsdScan->nPSDStartPoint; i<=pPsdScan->nPSDStopPoint; i++) + { + if (pPsdScan->nPSDReport[i] > pPsdScan->nPSDReport_MaxHold[i]) + pPsdScan->nPSDReport_MaxHold[i] = pPsdScan->nPSDReport[i]; + + //search Max Value + if (i ==pPsdScan->nPSDStartPoint ) + { + i_max = i; + val_max = pPsdScan->nPSDReport_MaxHold[i]; + } + else + { + if (pPsdScan->nPSDReport_MaxHold[i] > val_max) + { + i_max = i; + val_max = pPsdScan->nPSDReport_MaxHold[i]; + } + } + + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i = %d, PSDReport = %d dB\n", i, pPsdScan->nPSDReport_MaxHold[i]); + + } + + pPsdScan->nPSDMaxValuePoint = i_max; + pPsdScan->nPSDMaxValue = val_max; + + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i_Max = %d, PSDReport_Max = %d dB, TotalCnt = %d\n", pPsdScan->nPSDMaxValuePoint + ,pPsdScan->nPSDMaxValue, pPsdScan->nPSDGenTotalCount); + } + + if (pPsdScan->nPSDGenCount+1 <= pPsdScan->realseconds) + { + pPsdScan->nPSDGenCount++; + pPsdScan->nPSDGenTotalCount++; + } + else + { + break; + } + + } while (1); + //Set Antenna Path + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + + //Resume Coex DM + pBtCoexist->bStopCoexDm = FALSE; + +} + //============================================================ // work around function start with wa_halbtc8723b1ant_ @@ -3059,6 +3664,13 @@ EXhalbtc8723b1ant_PowerOnSetting( } } +VOID +EXhalbtc8723b1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + VOID EXhalbtc8723b1ant_InitHwConfig( IN PBTC_COEXIST pBtCoexist, @@ -3095,14 +3707,16 @@ EXhalbtc8723b1ant_DisplayCoexInfo( u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u2Byte u2Tmp[4]; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE, bWifiUnderBMode = FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir, faOfdm, faCck, wifiLinkStatus; - u1Byte wifiDot11Chnl, wifiHsChnl, apNum; + u4Byte faOfdm, faCck; u4Byte fwVer=0, btPatchVer=0; static u1Byte PopReportIn10s = 0; + if (pPsdScan->bIsAntDetEnable == TRUE) + { + halbtc8723b1ant_ShowPSDData(pBtCoexist); + return; + } + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); CL_PRINTF(cliBuf); @@ -3135,51 +3749,24 @@ EXhalbtc8723b1ant_DisplayCoexInfo( GLCoexVerDate8723b1Ant, GLCoexVer8723b1Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi-100, btHsRssi-100); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "Wifi bHi-Pri/ CCK lock/ CCK ever-lock", \ + (pCoexSta->bWiFiIsHighPriTask? "Yes":"No"), + (pCoexSta->bCCKLock? "Yes":"No"), + (pCoexSta->bCCKEverLock? "Yes":"No")); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %s", "Wifi bLink/ bRoam/ bScan/ bHi-Pri", \ - bLink, bRoam, bScan,((pCoexSta->bWiFiIsHighPriTask)? "1":"0")); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s/ AP=%d/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((bWifiUnderBMode)? "11b": ((BTC_WIFI_BW_LEGACY==wifiBw)? "11bg": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20")))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink")), pCoexSta->nScanAPNum,( pCoexSta->bCCKLock)? "Lock":"noLock"); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "sta/vwifi/hs/p2pGo/p2pGc", \ - ((wifiLinkStatus&WIFI_STA_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_AP_CONNECTED)? 1:0), - ((wifiLinkStatus&WIFI_HS_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_P2P_GO_CONNECTED)? 1:0), - ((wifiLinkStatus&WIFI_P2P_GC_CONNECTED)? 1:0) ); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); - PopReportIn10s++; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d/ %d] ", "BT [status/ rssi/ retryCnt/ popCnt]", \ ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": @@ -3193,9 +3780,8 @@ EXhalbtc8723b1ant_DisplayCoexInfo( PopReportIn10s = 0; } - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ - pBtLinkInfo->bScoExist, pBtLinkInfo->bHidExist, pBtLinkInfo->bPanExist, pBtLinkInfo->bA2dpExist); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d / %d", "SCO/HID/PAN/A2DP/Hi-Pri", \ + pBtLinkInfo->bScoExist, pBtLinkInfo->bHidExist, pBtLinkInfo->bPanExist, pBtLinkInfo->bA2dpExist, pBtLinkInfo->bBtHiPriLinkExist); CL_PRINTF(cliBuf); if (pStackInfo->bProfileNotified) @@ -3209,7 +3795,6 @@ EXhalbtc8723b1ant_DisplayCoexInfo( CL_PRINTF(cliBuf); } - btInfoExt = pCoexSta->btInfoExt; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ (btInfoExt&BIT0)? "Basic rate":"EDR rate"); @@ -3227,13 +3812,6 @@ EXhalbtc8723b1ant_DisplayCoexInfo( CL_PRINTF(cliBuf); } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s, (0x%x/0x%x)", "PS state, IPS/LPS, (lps/rpwm)", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF")), - pBtCoexist->btInfo.lpsVal, - pBtCoexist->btInfo.rpwmVal); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); if(!pBtCoexist->bManualControl) { @@ -3399,8 +3977,8 @@ EXhalbtc8723b1ant_IpsNotify( pCoexSta->bUnderIps = TRUE; halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); //halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); } else if(BTC_IPS_LEAVE == type) @@ -3461,6 +4039,7 @@ EXhalbtc8723b1ant_ScanNotify( BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN START notify\n")); halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); @@ -3553,6 +4132,7 @@ EXhalbtc8723b1ant_ConnectNotify( { pCoexSta->bWiFiIsHighPriTask = TRUE; halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], CONNECT START notify\n")); pCoexDm->nArpCnt = 0; } @@ -3626,6 +4206,7 @@ EXhalbtc8723b1ant_MediaStatusNotify( { BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], MEDIA connect notify\n")); halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); //Set CCK Tx/Rx high Pri except 11b mode @@ -3652,6 +4233,8 @@ EXhalbtc8723b1ant_MediaStatusNotify( pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x0); //CCK Tx pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x0); //CCK Rx + + pCoexSta->bCCKEverLock = FALSE; } // only 2.4G we need to inform bt the chnl mask @@ -3796,6 +4379,12 @@ EXhalbtc8723b1ant_BtInfoNotify( } } + // if 0xff, it means BT is under WHCK test + if (btInfo == 0xff) + pCoexSta->bBtWhckTest = TRUE; + else + pCoexSta->bBtWhckTest = FALSE; + if(BT_INFO_SRC_8723B_1ANT_WIFI_FW != rspSource) { pCoexSta->btRetryCnt = // [3:0] @@ -3879,6 +4468,8 @@ EXhalbtc8723b1ant_BtInfoNotify( pCoexSta->bA2dpExist = FALSE; pCoexSta->bHidExist = FALSE; pCoexSta->bScoExist = FALSE; + + pCoexSta->bBtHiPriLinkExist = FALSE; } else // connection exists { @@ -3899,6 +4490,17 @@ EXhalbtc8723b1ant_BtInfoNotify( pCoexSta->bScoExist = TRUE; else pCoexSta->bScoExist = FALSE; + + if ( (pCoexSta->bHidExist == FALSE) && (pCoexSta->bC2hBtInquiryPage == FALSE) ) + { + if (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + pCoexSta->bHidExist = TRUE; + } + + //Add Hi-Pri Tx/Rx counter to avoid false detection + if ( ( (pCoexSta->bHidExist) || (pCoexSta->bScoExist) ) && (pCoexSta->highPriorityTx > 60) && (pCoexSta->highPriorityRx > 60) + && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->bBtHiPriLinkExist = TRUE; } halbtc8723b1ant_UpdateBtLinkInfo(pBtCoexist); @@ -3953,7 +4555,7 @@ EXhalbtc8723b1ant_RfStatusNotify( { u4Byte u4Tmp; u1Byte u1Tmpa,u1Tmpb, u1Tmpc; - + BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], RF Status notify\n")); if(BTC_RF_ON == type) @@ -3967,7 +4569,7 @@ EXhalbtc8723b1ant_RfStatusNotify( halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); //halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); halbtc8723b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); @@ -3975,11 +4577,13 @@ EXhalbtc8723b1ant_RfStatusNotify( u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); - u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); u1Tmpc = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x, 0x76e=0x%x\n", - u4Tmp, u1Tmpa, u1Tmpb, u1Tmpc)); + u4Tmp, u1Tmpa, u1Tmpb, u1Tmpc)); + } } @@ -3994,7 +4598,7 @@ EXhalbtc8723b1ant_HaltNotify( halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); //halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); halbtc8723b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); @@ -4018,8 +4622,8 @@ EXhalbtc8723b1ant_PnpNotify( halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); - halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); //halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); pBtCoexist->bStopCoexDm = TRUE; @@ -4089,9 +4693,131 @@ EXhalbtc8723b1ant_Periodical( } pCoexSta->specialPktPeriodCnt++; + +/* + if (pPsdScan->bIsAntDetEnable) + { + if (pPsdScan->nPSDGenCount > pPsdScan->realseconds) + pPsdScan->nPSDGenCount = 0; + + halbtc8723b1ant_AntennaDetection(pBtCoexist, pPsdScan->realcentFreq, pPsdScan->realoffset, pPsdScan->realspan, pPsdScan->realseconds); + pPsdScan->nPSDGenTotalCount +=2; + pPsdScan->nPSDGenCount += 2; + } +*/ #endif } +VOID +EXhalbtc8723b1ant_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + pPsdScan->bIsAntDetEnable = FALSE; + + //do antenna detection periodically (every 2 seconds) + if (centFreq == 0) + { + return; + } + else + { + //parse parameter + pPsdScan->realcentFreq = ((centFreq & 0xf000) >> 12) * 1000 + ((centFreq & 0xf00) >> 8) * 100 + + ((centFreq & 0xf0) >> 4) * 10 + (centFreq & 0xf); + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), real freq = %d\n", pPsdScan->realcentFreq); + + + pPsdScan->realoffset =( (offset & 0x70) >> 4) * 10 + (offset & 0xf); + if (offset & 0x80) + pPsdScan->realoffset = 0 - pPsdScan->realoffset; + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), real offst = %d\n", pPsdScan->realoffset); + + if (span & 0x80) + pPsdScan->bIsPSDShowMaxOnly = TRUE; + else + pPsdScan->bIsPSDShowMaxOnly = FALSE; + pPsdScan->realspan = ((span & 0x70) >> 4) * 10 + (span & 0xf); + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), real span = %d\n", pPsdScan->realspan); + + if ( (pPsdScan->realcentFreq < 2412) || ( (pPsdScan->realcentFreq > 2472) && (pPsdScan->realcentFreq != 2484) ) ) + { + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), center freq is not valid!!\n"); + return; + + } + else if ( ( (pPsdScan->realcentFreq - 2412) % 5 != 0 ) && (pPsdScan->realcentFreq != 2484) ) + { + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), center freq is not valid!!\n"); + return; + } + + if ( (pPsdScan->realoffset > 20) || (pPsdScan->realoffset < -20) ) + { + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), freq offset is not valid!!\n"); + return; + } + + if (pPsdScan->realspan > 40) + { + DbgPrint("xxxxxxxxxxxxxxxx SweepPSDPoint(), freq span is not valid!!\n"); + return; + } + + pPsdScan->realseconds =( (seconds & 0xf0) >> 4) * 10 + (seconds & 0xf); + pPsdScan->nPSDGenCount = 0; + pPsdScan->nPSDGenTotalCount= 0; + } + + + pPsdScan->bIsAntDetEnable = TRUE; + + + halbtc8723b1ant_AntennaDetection(pBtCoexist, pPsdScan->realcentFreq, pPsdScan->realoffset, pPsdScan->realspan, pPsdScan->realseconds); + + + +} + +VOID +EXhalbtc8723b1ant_AntennaIsolation( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + + +} + +VOID +EXhalbtc8723b1ant_PSDScan( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + + +} + +VOID +EXhalbtc8723b1ant_DisplayAntIsolation( + IN PBTC_COEXIST pBtCoexist + ) +{ + + //halbtc8723b1ant_ShowPSDData(pBtCoexist); +} + #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.h index 9ebec684988e..248874d55f56 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.h @@ -62,6 +62,9 @@ typedef enum _BT_8723B_1ANT_COEX_ALGO{ }BT_8723B_1ANT_COEX_ALGO,*PBT_8723B_1ANT_COEX_ALGO; typedef struct _COEX_DM_8723B_1ANT{ + // hw setting + u1Byte preAntPosType; + u1Byte curAntPosType; // fw mechanism BOOLEAN bCurIgnoreWlanAct; BOOLEAN bPreIgnoreWlanAct; @@ -122,6 +125,7 @@ typedef struct _COEX_STA_8723B_1ANT{ BOOLEAN bA2dpExist; BOOLEAN bHidExist; BOOLEAN bPanExist; + BOOLEAN bBtHiPriLinkExist; BOOLEAN bUnderLps; BOOLEAN bUnderIps; @@ -137,6 +141,7 @@ typedef struct _COEX_STA_8723B_1ANT{ BOOLEAN bC2hBtInfoReqSent; u1Byte btInfoC2h[BT_INFO_SRC_8723B_1ANT_MAX][10]; u4Byte btInfoC2hCnt[BT_INFO_SRC_8723B_1ANT_MAX]; + BOOLEAN bBtWhckTest; BOOLEAN bC2hBtInquiryPage; BOOLEAN bC2hBtPage; //Add for win8.1 page out issue BOOLEAN bWiFiIsHighPriTask; //Add for win8.1 page out issue @@ -157,11 +162,45 @@ typedef struct _COEX_STA_8723B_1ANT{ BOOLEAN bCCKLock; BOOLEAN bPreCCKLock; + BOOLEAN bCCKEverLock; u1Byte nCoexTableType; BOOLEAN bForceLpsOn; }COEX_STA_8723B_1ANT, *PCOEX_STA_8723B_1ANT; +#define BT_8723B_1ANT_ANTDET_PSD_POINTS 256 //MAX:1024 +#define BT_8723B_1ANT_ANTDET_PSD_AVGNUM 1 //MAX:3 + +typedef struct _PSDSCAN_STA_8723B_1ANT{ + +BOOLEAN bIsAntDetEnable; +BOOLEAN bIsAntIsoEnable; +BOOLEAN bIsPSDScanEnable; + +u4Byte realcentFreq; //ex:2412 +s4Byte realoffset; +u4Byte realspan; +u4Byte realseconds; + +BOOLEAN bAntDetFinish; +u1Byte nAntIsolation; +u4Byte nPSDBandWidth; //unit: Hz +u4Byte nPSDPoint; //128/256/512/1024 +u4Byte nPSDReport[1024]; //unit:dB (20logx), 0~255 +u4Byte nPSDReport_MaxHold[1024]; //unit:dB (20logx), 0~255 +u4Byte nPSDStartPoint; +u4Byte nPSDStopPoint; +u4Byte nPSDMaxValuePoint; +u4Byte nPSDMaxValue; +u4Byte nPSDStartBase; +u4Byte nPSDAvgNum; // 1/8/16/32 +u4Byte nPSDGenCount; +u4Byte nPSDGenTotalCount; +BOOLEAN bIsSetupFinish; +BOOLEAN bIsPSDRunning; +BOOLEAN bIsPSDShowMaxOnly; +} PSDSCAN_STA_8723B_1ANT, *PPSDSCAN_STA_8723B_1ANT; + //=========================================== // The following is interface which will notify coex module. //=========================================== @@ -170,6 +209,10 @@ EXhalbtc8723b1ant_PowerOnSetting( IN PBTC_COEXIST pBtCoexist ); VOID +EXhalbtc8723b1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID EXhalbtc8723b1ant_InitHwConfig( IN PBTC_COEXIST pBtCoexist, IN BOOLEAN bWifiOnly @@ -240,4 +283,33 @@ VOID EXhalbtc8723b1ant_DisplayCoexInfo( IN PBTC_COEXIST pBtCoexist ); +VOID +EXhalbtc8723b1ant_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ); +VOID +EXhalbtc8723b1ant_AntennaIsolation( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ); + +VOID +EXhalbtc8723b1ant_PSDScan( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ); +VOID +EXhalbtc8723b1ant_DisplayAntIsolation( + IN PBTC_COEXIST pBtCoexist + ); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.c index 34795bd91d4f..c0ced8e21a89 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.c @@ -27,8 +27,8 @@ const char *const GLBtInfoSrc8723b2Ant[]={ "BT Info[bt auto report]", }; -u4Byte GLCoexVerDate8723b2Ant=20131211; -u4Byte GLCoexVer8723b2Ant=0x40; +u4Byte GLCoexVerDate8723b2Ant=20140903; +u4Byte GLCoexVer8723b2Ant=0x43; //============================================================ // local function proto type if needed @@ -337,6 +337,8 @@ halbtc8723b2ant_MonitorBtCtr( u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; u1Byte u1Tmp; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + regHPTxRx = 0x770; regLPTxRx = 0x774; @@ -353,6 +355,15 @@ halbtc8723b2ant_MonitorBtCtr( pCoexSta->lowPriorityTx = regLPTx; pCoexSta->lowPriorityRx = regLPRx; + if ( (pCoexSta->lowPriorityRx >= 950) && (pCoexSta->lowPriorityRx >= pCoexSta->lowPriorityTx) && (!pCoexSta->bUnderIps) ) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", @@ -362,6 +373,48 @@ halbtc8723b2ant_MonitorBtCtr( pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); } +VOID +halbtc8723b2ant_MonitorWiFiCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + u2Byte u2Tmp[3]; + s4Byte wifiRssi=0; + BOOLEAN bWifiBusy = FALSE, bWifiUnderBMode = FALSE; + static u1Byte nCCKLockCounter = 0; + + + if (pCoexSta->bUnderIps) + { + pCoexSta->nCRCOK_CCK = 0; + pCoexSta->nCRCOK_11g = 0; + pCoexSta->nCRCOK_11n = 0; + pCoexSta->nCRCOK_11nAgg = 0; + + pCoexSta->nCRCErr_CCK = 0; + pCoexSta->nCRCErr_11g = 0; + pCoexSta->nCRCErr_11n = 0; + pCoexSta->nCRCErr_11nAgg = 0; + } + else + { + pCoexSta->nCRCOK_CCK = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xf88); + pCoexSta->nCRCOK_11g = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf94); + pCoexSta->nCRCOK_11n = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf90); + pCoexSta->nCRCOK_11nAgg= pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xfb8); + + pCoexSta->nCRCErr_CCK = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xf84); + pCoexSta->nCRCErr_11g = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf96); + pCoexSta->nCRCErr_11n = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf92); + pCoexSta->nCRCErr_11nAgg = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xfba); + } + + //reset counter + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xf16, 0x1, 0x1); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xf16, 0x1, 0x0); +} + VOID halbtc8723b2ant_QueryBtInfo( IN PBTC_COEXIST pBtCoexist @@ -387,6 +440,8 @@ halbtc8723b2ant_IsWifiStatusChanged( static BOOLEAN bPreWifiBusy=FALSE, bPreUnder4way=FALSE, bPreBtHsOn=FALSE; BOOLEAN bWifiBusy=FALSE, bUnder4way=FALSE, bBtHsOn=FALSE; BOOLEAN bWifiConnected=FALSE; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); @@ -410,6 +465,15 @@ halbtc8723b2ant_IsWifiStatusChanged( bPreBtHsOn = bBtHsOn; return TRUE; } + + + wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist,3, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + + if ( (BTC_RSSI_STATE_HIGH ==wifiRssiState ) || (BTC_RSSI_STATE_LOW ==wifiRssiState )) + { + return TRUE; + } + } return FALSE; @@ -1201,46 +1265,57 @@ halbtc8723b2ant_CoexTableWithType( IN u1Byte type ) { + pCoexSta->nCoexTableType = type; + switch(type) { case 0: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); break; case 1: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5afa5afa, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5afa5afa, 0xffffff, 0x3); break; case 2: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5ada5ada, 0x5ada5ada, 0xffffff, 0x3); break; case 3: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); break; case 4: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xffffffff, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xffffffff, 0xffffff, 0x3); break; case 5: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5fff5fff, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5fff5fff, 0xffffff, 0x3); break; case 6: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5a5a5a5a, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5a5a5a5a, 0xffffff, 0x3); break; case 7: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0xfafafafa, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); break; case 8: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); break; case 9: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5aea5aea, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); break; case 10: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5aff5aff, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); break; case 11: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5a5f5a5f, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); break; case 12: - halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5f5f5f5f, 0xffff, 0x3); + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 13: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 14: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5ada5ada, 0xffffff, 0x3); + break; + case 15: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0xaaaaaaaa, 0xffffff, 0x3); break; default: break; @@ -1266,6 +1341,55 @@ halbtc8723b2ant_SetFwIgnoreWlanAct( pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); } +VOID +halbtc8723b2ant_SetLpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + u1Byte lps=lpsVal; + u1Byte rpwm=rpwmVal; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_LPS_VAL, &lps); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RPWM_VAL, &rpwm); +} + +VOID +halbtc8723b2ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], LPS-RxBeaconMode=0x%x , LPS-RPWM=0x%x!!\n", + pCoexDm->curLps, pCoexDm->curRpwm)); + + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], LPS-RPWM_Last=0x%x , LPS-RPWM_Now=0x%x!!\n", + pCoexDm->preRpwm, pCoexDm->curRpwm)); + + return; + } + } + halbtc8723b2ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + VOID halbtc8723b2ant_IgnoreWlanAct( IN PBTC_COEXIST pBtCoexist, @@ -1302,6 +1426,12 @@ halbtc8723b2ant_SetFwPstdma( { u1Byte H2C_Parameter[5] ={0}; + + if ( (pCoexSta->bA2dpExist) && (pCoexSta->bHidExist) ) + { + byte5 = byte5 | 0x1; + } + H2C_Parameter[0] = byte1; H2C_Parameter[1] = byte2; H2C_Parameter[2] = byte3; @@ -1342,7 +1472,7 @@ halbtc8723b2ant_SwMechanism1( } */ - halbtc8723b2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); + //halbtc8723b2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); halbtc8723b2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); } @@ -1355,9 +1485,9 @@ halbtc8723b2ant_SwMechanism2( IN u4Byte dacSwingLvl ) { - halbtc8723b2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); + //halbtc8723b2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); //halbtc8723b2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff); - halbtc8723b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); + //halbtc8723b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); } VOID @@ -1390,19 +1520,20 @@ halbtc8723b2ant_SetAntPath( if(fwVer >= 0x180000) { - /* Use H2C to set GNT_BT to LOW */ - H2C_Parameter[0] = 0; + /* Use H2C to set GNT_BT to High to avoid A2DP click */ + H2C_Parameter[0] = 1; pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); } else { - pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x0); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18); } pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); //WiFi TRx Mask off - pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x01); //BT TRx Mask off + //remove due to interrupt is disabled that polling c2h will fail and delay 100ms. + //pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x01); //BT TRx Mask off if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) { @@ -1427,6 +1558,19 @@ halbtc8723b2ant_SetAntPath( } pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); } + else + { + if(fwVer >= 0x180000) + { + /* Use H2C to set GNT_BT to "Control by PTA"*/ + H2C_Parameter[0] = 0; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); + } + else + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x0); + } + } // ext switch setting if(bUseExtSwitch) @@ -1485,6 +1629,16 @@ halbtc8723b2ant_PsTdma( { BOOLEAN bTurnOnByCnt=FALSE; u1Byte psTdmaTypeByCnt=0; + u1Byte wifiRssiState1, btRssiState; + + + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + if (!(BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) && bTurnOn) + { + type = type +100; //for WiFi RSSI low or BT RSSI low + } BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); @@ -1508,10 +1662,12 @@ halbtc8723b2ant_PsTdma( { case 1: default: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); break; case 2: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x03, 0xf1, 0x90); break; case 3: halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90); @@ -1520,10 +1676,12 @@ halbtc8723b2ant_PsTdma( halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x03, 0xf1, 0x90); break; case 5: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x3, 0x70, 0x90); break; case 6: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x3, 0x70, 0x90); break; case 7: halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90); @@ -1532,28 +1690,36 @@ halbtc8723b2ant_PsTdma( halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x10, 0x3, 0x70, 0x90); break; case 9: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); break; case 10: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x03, 0xf1, 0x90); break; case 11: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90); break; case 12: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0xf1, 0x90); break; case 13: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x3, 0x70, 0x90); break; case 14: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x3, 0x70, 0x90); break; case 15: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90); break; case 16: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0x60, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0x60, 0x90); + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0x70, 0x90); break; case 17: halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x2f, 0x2f, 0x60, 0x90); @@ -1571,7 +1737,45 @@ halbtc8723b2ant_PsTdma( halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); break; case 71: - halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + //halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 101: + case 105: + case 171: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x3a, 0x03, 0x70, 0x50); + break; + case 102: + case 106: + case 110: + case 114: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x2d, 0x03, 0x70, 0x50); + break; + case 103: + case 107: + case 111: + case 115: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1c, 0x03, 0x70, 0x50); + break; + case 104: + case 108: + case 112: + case 116: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x10, 0x03, 0x70, 0x50); + break; + case 109: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 113: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x70, 0x90); + break; + case 121: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); + break; + case 22: + case 122: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x35, 0x03, 0x71, 0x11); break; } } @@ -1597,12 +1801,89 @@ halbtc8723b2ant_PsTdma( pCoexDm->prePsTdma = pCoexDm->curPsTdma; } +VOID +halbtc8723b2ant_PsTdmaCheckForPowerSaveState( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bNewPsState + ) +{ + u1Byte lpsMode=0x0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_LPS_MODE, &lpsMode); + + if(lpsMode) // already under LPS state + { + if(bNewPsState) + { + // keep state under LPS, do nothing. + } + else + { + // will leave LPS state, turn off psTdma first + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8723b2ant_PowerSaveState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte psType, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bLowPwrDisable=FALSE; + + switch(psType) + { + case BTC_PS_WIFI_NATIVE: + // recover to original 32k low power setting + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + case BTC_PS_LPS_ON: + halbtc8723b2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8723b2ant_LpsRpwm(pBtCoexist, NORMAL_EXEC, lpsVal, rpwmVal); + // when coex force to enter LPS, do not enter 32k low power. + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + // power save must executed before psTdma. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_ENTER_LPS, NULL); + pCoexSta->bForceLpsOn = TRUE; + break; + case BTC_PS_LPS_OFF: + halbtc8723b2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + + VOID halbtc8723b2ant_CoexAllOff( IN PBTC_COEXIST pBtCoexist ) { // fw all off + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); @@ -1622,7 +1903,9 @@ halbtc8723b2ant_InitCoexDm( ) { // force to reset coex mechanism + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); halbtc8723b2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, 0); @@ -1636,33 +1919,130 @@ halbtc8723b2ant_ActionBtInquiry( IN PBTC_COEXIST pBtCoexist ) { + u1Byte wifiRssiState, wifiRssiState1, btRssiState; BOOLEAN bWifiConnected=FALSE; BOOLEAN bLowPwrDisable=TRUE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + + wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); - if(bWifiConnected) + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); + + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if(bScan || bLink || bRoam) { - halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); - halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi link process + BT Inq/Page!!\n")); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + } + else if(bWifiConnected) + { + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi connected + BT Inq/Page!!\n")); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); } else { + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi no-link + BT Inq/Page!!\n")); halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); } + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); - +/* pCoexDm->bNeedRecover0x948 = TRUE; pCoexDm->backup0x948 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); halbtc8723b2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_AUX, FALSE, FALSE); +*/ } + + +VOID +halbtc8723b2ant_ActionWiFiLinkProcess( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + u1Byte u1Tmpa, u1Tmpb; + + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + + BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x76e=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); +} + +BOOLEAN +halbtc8723b2ant_ActionWifiIdleProcess( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + //wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES-20, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); + + // define the office environment + if(BTC_RSSI_HIGH(wifiRssiState1) && + (pCoexSta->bHidExist == TRUE) && (pCoexSta->bA2dpExist == TRUE)) + { + + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi idle process for BT HID+A2DP exist!!\n")); + + halbtc8723b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x6); + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + return TRUE; + } + else + { + halbtc8723b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + return FALSE; + } + + +} + + + BOOLEAN halbtc8723b2ant_IsCommonAction( IN PBTC_COEXIST pBtCoexist @@ -1671,6 +2051,7 @@ halbtc8723b2ant_IsCommonAction( u1Byte btRssiState=BTC_RSSI_STATE_HIGH; BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; BOOLEAN bBtHsOn=FALSE, bLowPwrDisable=FALSE; + BOOLEAN bAsus8723b=FALSE; pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); @@ -1686,6 +2067,8 @@ halbtc8723b2ant_IsCommonAction( pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); @@ -1707,6 +2090,8 @@ halbtc8723b2ant_IsCommonAction( pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xb); halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); @@ -1728,6 +2113,8 @@ halbtc8723b2ant_IsCommonAction( pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xb); halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); @@ -1745,28 +2132,17 @@ halbtc8723b2ant_IsCommonAction( if(bWifiBusy) { BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_IS_ASUS_8723B, &bAsus8723b); + if(!bAsus8723b) bCommon = FALSE; + else + bCommon = halbtc8723b2ant_ActionWifiIdleProcess(pBtCoexist); } else { - if(bBtHsOn) - return FALSE; - BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); - halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); - - pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); - halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); - halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 21); - halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xb); - if(BTC_RSSI_HIGH(btRssiState)) - halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); - else - halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); - halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); - halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); - bCommon = TRUE; + //bCommon = FALSE; + bCommon = halbtc8723b2ant_ActionWifiIdleProcess(pBtCoexist); } } } @@ -2694,7 +3070,7 @@ halbtc8723b2ant_ActionSco( u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -2718,6 +3094,7 @@ halbtc8723b2ant_ActionSco( halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); } + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); //for voice quality // sw mechanism @@ -2761,7 +3138,7 @@ halbtc8723b2ant_ActionHid( u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -2785,6 +3162,8 @@ halbtc8723b2ant_ActionHid( halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 9); } + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + if( (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { @@ -2837,20 +3216,25 @@ halbtc8723b2ant_ActionA2dp( u1Byte apNum=0; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, 40, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); // define the office environment - if(apNum >= 10 && BTC_RSSI_HIGH(wifiRssiState1)) + if( (apNum >= 10) && BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) { //DbgPrint(" AP#>10(%d)\n", apNum); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); - halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); // sw mechanism @@ -2866,6 +3250,7 @@ halbtc8723b2ant_ActionA2dp( halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x18); } return; + } pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -2878,7 +3263,18 @@ halbtc8723b2ant_ActionA2dp( else halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + if( (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) @@ -2927,11 +3323,12 @@ halbtc8723b2ant_ActionA2dpPanHs( IN PBTC_COEXIST pBtCoexist ) { - u1Byte wifiRssiState, btRssiState; + u1Byte wifiRssiState, wifiRssiState1, btRssiState; u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -2944,7 +3341,16 @@ halbtc8723b2ant_ActionA2dpPanHs( else halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 2); @@ -2985,11 +3391,12 @@ halbtc8723b2ant_ActionPanEdr( IN PBTC_COEXIST pBtCoexist ) { - u1Byte wifiRssiState, btRssiState; + u1Byte wifiRssiState,wifiRssiState1, btRssiState; u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -3002,7 +3409,16 @@ halbtc8723b2ant_ActionPanEdr( else halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 10); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } if( (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) @@ -3053,11 +3469,12 @@ halbtc8723b2ant_ActionPanHs( IN PBTC_COEXIST pBtCoexist ) { - u1Byte wifiRssiState, btRssiState; + u1Byte wifiRssiState, wifiRssiState1, btRssiState; u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -3072,6 +3489,7 @@ halbtc8723b2ant_ActionPanHs( halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); @@ -3111,11 +3529,12 @@ halbtc8723b2ant_ActionPanEdrA2dp( IN PBTC_COEXIST pBtCoexist ) { - u1Byte wifiRssiState, btRssiState; + u1Byte wifiRssiState, wifiRssiState1, btRssiState; u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -3128,12 +3547,18 @@ halbtc8723b2ant_ActionPanEdrA2dp( else halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); if( (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 12); + if(BTC_WIFI_BW_HT40 == wifiBw) halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); else @@ -3141,7 +3566,7 @@ halbtc8723b2ant_ActionPanEdrA2dp( } else { - halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); } @@ -3181,11 +3606,12 @@ halbtc8723b2ant_ActionPanEdrHid( IN PBTC_COEXIST pBtCoexist ) { - u1Byte wifiRssiState, btRssiState; + u1Byte wifiRssiState, wifiRssiState1, btRssiState; u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); @@ -3195,19 +3621,30 @@ halbtc8723b2ant_ActionPanEdrHid( else halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + if( (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { if(BTC_WIFI_BW_HT40 == wifiBw) { halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 3); - halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 11); + //halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 11); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); } else { halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); - halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + //halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); } halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); @@ -3215,7 +3652,7 @@ halbtc8723b2ant_ActionPanEdrHid( else { halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); - halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 11); + //halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); } @@ -3257,11 +3694,12 @@ halbtc8723b2ant_ActionHidA2dpPanEdr( IN PBTC_COEXIST pBtCoexist ) { - u1Byte wifiRssiState, btRssiState; + u1Byte wifiRssiState,wifiRssiState1, btRssiState; u4Byte wifiBw; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); - btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -3274,15 +3712,24 @@ halbtc8723b2ant_ActionHidA2dpPanEdr( else halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } - halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); if( (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { if(BTC_WIFI_BW_HT40 == wifiBw) - halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); else halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); } @@ -3327,13 +3774,14 @@ halbtc8723b2ant_ActionHidA2dp( IN PBTC_COEXIST pBtCoexist ) { - u1Byte wifiRssiState, btRssiState; + u1Byte wifiRssiState, wifiRssiState1, btRssiState; u4Byte wifiBw; u1Byte apNum=0; wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); //btRssiState = halbtc8723b2ant_BtRssiState(2, 29, 0); - btRssiState = halbtc8723b2ant_BtRssiState(3, 29, 37); + wifiRssiState1 = halbtc8723b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8723b2ant_BtRssiState(3, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 37); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); @@ -3368,16 +3816,25 @@ halbtc8723b2ant_ActionHidA2dp( halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); } + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } if( (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { - halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); } else { - halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); } // sw mechanism @@ -3411,6 +3868,43 @@ halbtc8723b2ant_ActionHidA2dp( } } +VOID +halbtc8723b2ant_ActionBtWhckTest( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8723b2ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8723b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); +} + VOID halbtc8723b2ant_RunCoexistMechanism( IN PBTC_COEXIST pBtCoexist @@ -3419,6 +3913,11 @@ halbtc8723b2ant_RunCoexistMechanism( BOOLEAN bWifiUnder5G=FALSE, bBtHsOn=FALSE; u1Byte btInfoOriginal=0, btRetryCnt=0; u1Byte algorithm=0; + u4Byte numOfWifiLink=0; + u4Byte wifiLinkStatus=0; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bMiracastPlusBt=FALSE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism()===>\n")); @@ -3434,6 +3933,13 @@ halbtc8723b2ant_RunCoexistMechanism( return; } + if(pCoexSta->bBtWhckTest) + { + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BT is under WHCK TEST!!!\n")); + halbtc8723b2ant_ActionBtWhckTest(pBtCoexist); + return; + } + algorithm = halbtc8723b2ant_ActionAlgorithm(pBtCoexist); if(pCoexSta->bC2hBtInquiryPage && (BT_8723B_2ANT_COEX_ALGO_PANHS!=algorithm)) { @@ -3443,11 +3949,53 @@ halbtc8723b2ant_RunCoexistMechanism( } else { + /* if(pCoexDm->bNeedRecover0x948) { pCoexDm->bNeedRecover0x948 = FALSE; pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, pCoexDm->backup0x948); } + */ + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); + + if(bScan || bLink || bRoam) + { + BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], WiFi is under Link Process !!\n")); + halbtc8723b2ant_ActionWiFiLinkProcess(pBtCoexist); + return; + } + + //for P2P + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + + if((numOfWifiLink>=2) || (wifiLinkStatus&WIFI_P2P_GO_CONNECTED)) + { + BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("############# [BTCoex], Multi-Port numOfWifiLink = %d, wifiLinkStatus = 0x%x\n", numOfWifiLink,wifiLinkStatus) ); + + if(pBtLinkInfo->bBtLinkExist) + { + bMiracastPlusBt = TRUE; + } + else + { + bMiracastPlusBt = FALSE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + halbtc8723b2ant_ActionWifiMultiPort(pBtCoexist); + + return; + } + else + { + bMiracastPlusBt = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); } pCoexDm->curAlgorithm = algorithm; @@ -3576,12 +4124,13 @@ halbtc8723b2ant_InitHwConfig( //Antenna config halbtc8723b2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_MAIN, TRUE, FALSE); + pCoexSta->disVerInfoCnt = 0; // PTA parameter halbtc8723b2ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); // Enable counter statistics - pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); //0x76e[3] =1, WLAN_Act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); //0x76e[3] =1, WLAN_Act control by PTA pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); } @@ -3598,7 +4147,6 @@ EXhalbtc8723b2ant_PowerOnSetting( ) { PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; - u1Byte u1Tmp=0x4; /* Set BIT2 by default since it's 2ant case */ u2Byte u2Tmp=0x0; pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x67, 0x20); @@ -3607,10 +4155,36 @@ EXhalbtc8723b2ant_PowerOnSetting( u2Tmp = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x2); pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x2, u2Tmp|BIT0|BIT1); - // set GRAN_BT = 1 - pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18); - // set WLAN_ACT = 0 - pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); + + if(pBtCoexist->chipInterface == BTC_INTF_USB) + { + // fixed at S0 for USB interface + pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_AUX_PORT; + } + else + { + // for PCIE and SDIO interface, we check efuse 0xc3[6] + if(pBoardInfo->singleAntPath == 0) + { + // set to S1 + pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; + } + else if(pBoardInfo->singleAntPath == 1) + { + // set to S0 + pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_AUX_PORT; + } + } +} + +VOID +EXhalbtc8723b2ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u1Byte u1Tmp=0x4; /* Set BIT2 by default since it's 2ant case */ // // S0 or S1 setting and Local register setting(By the setting fw can get ant number, S0/S1, ... info) @@ -3622,28 +4196,19 @@ EXhalbtc8723b2ant_PowerOnSetting( if(pBtCoexist->chipInterface == BTC_INTF_USB) { // fixed at S0 for USB interface - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); - u1Tmp |= 0x1; // antenna inverse pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0xfe08, u1Tmp); - - pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_AUX_PORT; } else { // for PCIE and SDIO interface, we check efuse 0xc3[6] if(pBoardInfo->singleAntPath == 0) { - // set to S1 - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280); - pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; } else if(pBoardInfo->singleAntPath == 1) { // set to S0 - pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); u1Tmp |= 0x1; // antenna inverse - pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_AUX_PORT; } if(pBtCoexist->chipInterface == BTC_INTF_PCI) @@ -3687,13 +4252,8 @@ EXhalbtc8723b2ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir, faOfdm, faCck; - u1Byte wifiDot11Chnl, wifiHsChnl; + u4Byte faOfdm, faCck; u4Byte fwVer=0, btPatchVer=0; - u1Byte apNum=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); CL_PRINTF(cliBuf); @@ -3720,52 +4280,39 @@ EXhalbtc8723b2ant_DisplayCoexInfo( GLCoexVerDate8723b2Ant, GLCoexVer8723b2Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "Wifi rssi/ HS rssi/ AP#", \ - wifiRssi, btHsRssi, apNum); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %ddBm/ %d] ", "BT [status/ rssi/ retryCnt]", \ ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": ( (BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), - pCoexSta->btRssi, pCoexSta->btRetryCnt); + pCoexSta->btRssi-100, pCoexSta->btRetryCnt); CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ pBtLinkInfo->bScoExist, pBtLinkInfo->bHidExist, pBtLinkInfo->bPanExist, pBtLinkInfo->bA2dpExist); CL_PRINTF(cliBuf); + + if (pStackInfo->bProfileNotified) + { pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Role", \ + (pBtLinkInfo->bSlaveRole )? "Slave":"Master"); + CL_PRINTF(cliBuf); + } btInfoExt = pCoexSta->btInfoExt; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ @@ -3785,12 +4332,6 @@ EXhalbtc8723b2ant_DisplayCoexInfo( } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", "PS state, IPS/LPS", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF"))); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); - // Sw mechanism CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============"); CL_PRINTF(cliBuf); @@ -3812,6 +4353,10 @@ EXhalbtc8723b2ant_DisplayCoexInfo( pCoexDm->psTdmaPara[4], psTdmaCase, pCoexDm->bAutoTdmaAdjust); CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "Coex Table Type", \ + pCoexSta->nCoexTableType); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", \ pCoexDm->curBtDecPwrLvl, pCoexDm->bCurIgnoreWlanAct); CL_PRINTF(cliBuf); @@ -3882,6 +4427,14 @@ EXhalbtc8723b2ant_DisplayCoexInfo( u4Tmp[0]&0xffff, faOfdm, faCck); CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", "CRC_OK CCK/11g/11n/11n-Agg", \ + pCoexSta->nCRCOK_CCK, pCoexSta->nCRCOK_11g, pCoexSta->nCRCOK_11n, pCoexSta->nCRCOK_11nAgg); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", "CRC_Err CCK/11g/11n/11n-Agg", \ + pCoexSta->nCRCErr_CCK, pCoexSta->nCRCErr_11g, pCoexSta->nCRCErr_11n, pCoexSta->nCRCErr_11nAgg); + CL_PRINTF(cliBuf); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); @@ -3897,7 +4450,7 @@ EXhalbtc8723b2ant_DisplayCoexInfo( pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); CL_PRINTF(cliBuf); #if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) - halbtc8723b2ant_MonitorBtCtr(pBtCoexist); + //halbtc8723b2ant_MonitorBtCtr(pBtCoexist); #endif pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); } @@ -3951,6 +4504,15 @@ EXhalbtc8723b2ant_ScanNotify( IN u1Byte type ) { + u4Byte u4Tmp; + u1Byte u1Tmpa, u1Tmpb; + + + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + if(BTC_SCAN_START == type) { BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN START notify\n")); @@ -3959,6 +4521,9 @@ EXhalbtc8723b2ant_ScanNotify( { BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN FINISH notify\n")); } + + BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x76e=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); } VOID @@ -4083,6 +4648,12 @@ EXhalbtc8723b2ant_BtInfoNotify( return; } + // if 0xff, it means BT is under WHCK test + if (btInfo == 0xff) + pCoexSta->bBtWhckTest = TRUE; + else + pCoexSta->bBtWhckTest = FALSE; + if(BT_INFO_SRC_8723B_2ANT_WIFI_FW != rspSource) { pCoexSta->btRetryCnt = // [3:0] @@ -4174,6 +4745,12 @@ EXhalbtc8723b2ant_BtInfoNotify( pCoexSta->bScoExist = TRUE; else pCoexSta->bScoExist = FALSE; + + if ( (pCoexSta->bHidExist == FALSE) && (pCoexSta->bC2hBtInquiryPage == FALSE) ) + { + if (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + pCoexSta->bHidExist = TRUE; + } } halbtc8723b2ant_UpdateBtLinkInfo(pBtCoexist); @@ -4234,7 +4811,8 @@ EXhalbtc8723b2ant_HaltNotify( BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Halt notify\n")); halbtc8723b2ant_WifiOffHwCfg(pBtCoexist); - pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); //BT goto standby while GNT_BT 1-->0 + //remove due to interrupt is disabled that polling c2h will fail and delay 100ms. + //pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); //BT goto standby while GNT_BT 1-->0 halbtc8723b2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); EXhalbtc8723b2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); @@ -4266,16 +4844,16 @@ EXhalbtc8723b2ant_Periodical( IN PBTC_COEXIST pBtCoexist ) { - static u1Byte disVerInfoCnt=0; + //static u1Byte disVerInfoCnt=0; u4Byte fwVer=0, btPatchVer=0; PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], ==========================Periodical===========================\n")); - if(disVerInfoCnt <= 5) + if(pCoexSta->disVerInfoCnt <= 5) { - disVerInfoCnt += 1; + pCoexSta->disVerInfoCnt += 1; BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], ****************************************************************\n")); BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", \ pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); @@ -4286,13 +4864,22 @@ EXhalbtc8723b2ant_Periodical( BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", \ GLCoexVerDate8723b2Ant, GLCoexVer8723b2Ant, fwVer, btPatchVer, btPatchVer)); BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], ****************************************************************\n")); + + if (pCoexSta->disVerInfoCnt == 3) + { + //Antenna config to set 0x765 = 0x0 (GNT_BT control by PTA) after initial + BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], Set GNT_BT control by PTA\n")); + halbtc8723b2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_MAIN, FALSE, FALSE); + } } #if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 0) halbtc8723b2ant_QueryBtInfo(pBtCoexist); - halbtc8723b2ant_MonitorBtCtr(pBtCoexist); halbtc8723b2ant_MonitorBtEnableDisable(pBtCoexist); #else + halbtc8723b2ant_MonitorBtCtr(pBtCoexist); + halbtc8723b2ant_MonitorWiFiCtr(pBtCoexist); + if( halbtc8723b2ant_IsWifiStatusChanged(pBtCoexist) || pCoexDm->bAutoTdmaAdjust) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.h index d16466d18f79..2c049f9fcebf 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.h @@ -15,6 +15,10 @@ #define BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT 2 + +#define BT_8723B_2ANT_WIFI_RSSI_COEXSWITCH_THRES 42 //WiFi RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation +#define BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES 46 //BT RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation + typedef enum _BT_INFO_SRC_8723B_2ANT{ BT_INFO_SRC_8723B_2ANT_WIFI_FW = 0x0, BT_INFO_SRC_8723B_2ANT_BT_RSP = 0x1, @@ -98,6 +102,11 @@ typedef struct _COEX_DM_8723B_2ANT{ BOOLEAN bNeedRecover0x948; u4Byte backup0x948; + + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; } COEX_DM_8723B_2ANT, *PCOEX_DM_8723B_2ANT; typedef struct _COEX_STA_8723B_2ANT{ @@ -120,9 +129,25 @@ typedef struct _COEX_STA_8723B_2ANT{ BOOLEAN bC2hBtInfoReqSent; u1Byte btInfoC2h[BT_INFO_SRC_8723B_2ANT_MAX][10]; u4Byte btInfoC2hCnt[BT_INFO_SRC_8723B_2ANT_MAX]; + BOOLEAN bBtWhckTest; BOOLEAN bC2hBtInquiryPage; u1Byte btRetryCnt; u1Byte btInfoExt; + + u4Byte nCRCOK_CCK; + u4Byte nCRCOK_11g; + u4Byte nCRCOK_11n; + u4Byte nCRCOK_11nAgg; + + u4Byte nCRCErr_CCK; + u4Byte nCRCErr_11g; + u4Byte nCRCErr_11n; + u4Byte nCRCErr_11nAgg; + + u1Byte nCoexTableType; + BOOLEAN bForceLpsOn; + + u1Byte disVerInfoCnt; }COEX_STA_8723B_2ANT, *PCOEX_STA_8723B_2ANT; //=========================================== @@ -133,6 +158,10 @@ EXhalbtc8723b2ant_PowerOnSetting( IN PBTC_COEXIST pBtCoexist ); VOID +EXhalbtc8723b2ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID EXhalbtc8723b2ant_InitHwConfig( IN PBTC_COEXIST pBtCoexist, IN BOOLEAN bWifiOnly diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a1Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a1Ant.c index d705431b51b3..d081053b8c5c 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a1Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a1Ant.c @@ -2168,11 +2168,6 @@ EXhalbtc8812a1ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; u4Byte fwVer=0, btPatchVer=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); @@ -2207,40 +2202,19 @@ EXhalbtc8812a1ant_DisplayCoexInfo( GLCoexVerDate8812a1Ant, GLCoexVer8812a1Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); - CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": ( (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), @@ -2269,13 +2243,6 @@ EXhalbtc8812a1ant_DisplayCoexInfo( CL_PRINTF(cliBuf); } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s, (0x%x/0x%x)", "PS state, IPS/LPS, (lps/rpwm)", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF")), - pBtCoexist->btInfo.lpsVal, - pBtCoexist->btInfo.rpwmVal); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); if(!pBtCoexist->bManualControl) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a2Ant.c index e0737098f83d..82029305e9b1 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8812a2Ant.c @@ -4163,11 +4163,6 @@ EXhalbtc8812a2ant_DisplayCoexInfo( u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u2Byte u2Tmp[4]; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; u4Byte fwVer=0, btPatchVer=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); @@ -4195,41 +4190,18 @@ EXhalbtc8812a2ant_DisplayCoexInfo( GLCoexVerDate8812a2Ant, GLCoexVer8812a2Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsMode(HsChnl)", \ - wifiDot11Chnl, bBtHsOn, wifiHsChnl); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); - CL_PRINTF(cliBuf); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8812A_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": ( (BT_8812A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), @@ -4259,15 +4231,6 @@ EXhalbtc8812a2ant_DisplayCoexInfo( } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s, (0x%x/0x%x)", "PS state, IPS/LPS, (lps/rpwm)", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF")), - pBtCoexist->btInfo.lpsVal, - pBtCoexist->btInfo.rpwmVal); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); - // Sw mechanism CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============"); CL_PRINTF(cliBuf); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a1Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a1Ant.c index 130566a2f6d4..c05c7668623d 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a1Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a1Ant.c @@ -2650,11 +2650,7 @@ EXhalbtc8821a1ant_DisplayCoexInfo( u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u2Byte u2Tmp[4]; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir, faOfdm, faCck, wifiLinkStatus; - u1Byte wifiDot11Chnl, wifiHsChnl; + u4Byte faOfdm, faCck; u4Byte fwVer=0, btPatchVer=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); @@ -2689,46 +2685,17 @@ EXhalbtc8821a1ant_DisplayCoexInfo( GLCoexVerDate8821a1Ant, GLCoexVer8821a1Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \ - wifiDot11Chnl, wifiHsChnl, bBtHsOn); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "sta/vwifi/hs/p2pGo/p2pGc", \ - ((wifiLinkStatus&WIFI_STA_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_AP_CONNECTED)? 1:0), - ((wifiLinkStatus&WIFI_HS_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_P2P_GO_CONNECTED)? 1:0), - ((wifiLinkStatus&WIFI_P2P_GC_CONNECTED)? 1:0) ); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ @@ -2759,13 +2726,6 @@ EXhalbtc8821a1ant_DisplayCoexInfo( CL_PRINTF(cliBuf); } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s, (0x%x/0x%x)", "PS state, IPS/LPS, (lps/rpwm)", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF")), - pBtCoexist->btInfo.lpsVal, - pBtCoexist->btInfo.rpwmVal); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); if(!pBtCoexist->bManualControl) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.c index 520c76960292..14ad651a9eb3 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.c @@ -3572,11 +3572,6 @@ EXhalbtc8821a2ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; u4Byte fwVer=0, btPatchVer=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); @@ -3602,39 +3597,17 @@ EXhalbtc8821a2ant_DisplayCoexInfo( GLCoexVerDate8821a2Ant, GLCoexVer8821a2Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsMode(HsChnl)", \ - wifiDot11Chnl, bBtHsOn, wifiHsChnl); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ @@ -3669,12 +3642,6 @@ EXhalbtc8821a2ant_DisplayCoexInfo( } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", "PS state, IPS/LPS", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF"))); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); - // Sw mechanism CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============"); CL_PRINTF(cliBuf); @@ -3768,12 +3735,6 @@ EXhalbtc8821a2ant_DisplayCoexInfo( pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); CL_PRINTF(cliBuf); - // Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang - u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x41b); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (mgntQ hang chk == 0xf)", \ - u1Tmp[0]); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821aCsr2Ant.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821aCsr2Ant.c index 9a7bed6f2523..824b8fbb0f69 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821aCsr2Ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtc8821aCsr2Ant.c @@ -16,6 +16,10 @@ #define _BTCOEX_CSR 1 +#ifndef rtw_warn_on + #define rtw_warn_on(condition) do {} while (0) +#endif + #if(BT_30_SUPPORT == 1) //============================================================ // Global variables, these are static variables @@ -1340,14 +1344,14 @@ halbtc8821aCsr2ant_SetFwPstdma( H2C_Parameter[2] = byte3; H2C_Parameter[3] = byte4; H2C_Parameter[4] = byte5; - H2C_Parameter[5] = 0x03; + H2C_Parameter[5] = 0x01; pCoexDm->psTdmaPara[0] = byte1; pCoexDm->psTdmaPara[1] = byte2; pCoexDm->psTdmaPara[2] = byte3; pCoexDm->psTdmaPara[3] = byte4; pCoexDm->psTdmaPara[4] = byte5; - pCoexDm->psTdmaPara[5] = 0x03; + pCoexDm->psTdmaPara[5] = 0x01; BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x60(6bytes)=0x%x%08x%02x\n", H2C_Parameter[0], @@ -1543,7 +1547,7 @@ halbtc8821aCsr2ant_PsTdma( halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); break; case 22: //ad2dp master - halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xeb, 0x12, 0x12, 0x21, 0x10); + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xeb, 0x11, 0x11, 0x21, 0x10); break; case 23: //a2dp slave halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xeb, 0x12, 0x12, 0x20, 0x10); @@ -3842,11 +3846,6 @@ EXhalbtc8821aCsr2ant_DisplayCoexInfo( pu1Byte cliBuf=pBtCoexist->cliBuf; u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; u4Byte u4Tmp[4]; - BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE; - BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; - s4Byte wifiRssi=0, btHsRssi=0; - u4Byte wifiBw, wifiTrafficDir; - u1Byte wifiDot11Chnl, wifiHsChnl; u4Byte fwVer=0, btPatchVer=0; CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); @@ -3872,39 +3871,17 @@ EXhalbtc8821aCsr2ant_DisplayCoexInfo( GLCoexVerDate8821aCsr2Ant, GLCoexVer8821aCsr2Ant, fwVer, btPatchVer, btPatchVer); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsMode(HsChnl)", \ - wifiDot11Chnl, bBtHsOn, wifiHsChnl); - CL_PRINTF(cliBuf); - - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \ + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "Wifi channel informed to BT", \ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1], pCoexDm->wifiChnlInfo[2]); CL_PRINTF(cliBuf); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ - wifiRssi, btHsRssi); + // wifi status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Wifi Status]============"); CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_WIFI_STATUS); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ - bLink, bRoam, bScan); - CL_PRINTF(cliBuf); - - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); - pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \ - (bWifiUnder5G? "5G":"2.4G"), - ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))), - ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink"))); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); CL_PRINTF(cliBuf); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \ @@ -3939,12 +3916,6 @@ EXhalbtc8821aCsr2ant_DisplayCoexInfo( } } - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", "PS state, IPS/LPS", \ - ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")), - ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF"))); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); - // Sw mechanism CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============"); CL_PRINTF(cliBuf); @@ -4038,12 +4009,6 @@ EXhalbtc8821aCsr2ant_DisplayCoexInfo( pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); CL_PRINTF(cliBuf); - // Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang - u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x41b); - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (mgntQ hang chk == 0xf)", \ - u1Tmp[0]); - CL_PRINTF(cliBuf); - pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtcOutSrc.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtcOutSrc.h index 9e235d62aba4..d74397076ee5 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtcOutSrc.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC-BTCoexist/HalBtcOutSrc.h @@ -203,10 +203,18 @@ typedef enum _BTC_WIFI_ROLE{ BTC_ROLE_MAX }BTC_WIFI_ROLE,*PBTC_WIFI_ROLE; +typedef enum _BTC_WIRELESS_FREQ{ + BTC_FREQ_2_4G = 0x0, + BTC_FREQ_5G = 0x1, + BTC_FREQ_MAX +}BTC_WIRELESS_FREQ,*PBTC_WIRELESS_FREQ; + typedef enum _BTC_WIFI_BW_MODE{ BTC_WIFI_BW_LEGACY = 0x0, BTC_WIFI_BW_HT20 = 0x1, BTC_WIFI_BW_HT40 = 0x2, + BTC_WIFI_BW_HT80 = 0x3, + BTC_WIFI_BW_HT160 = 0x4, BTC_WIFI_BW_MAX }BTC_WIFI_BW_MODE,*PBTC_WIFI_BW_MODE; @@ -233,6 +241,15 @@ typedef enum _BT_WIFI_COEX_STATE{ BTC_WIFI_STAT_MAX }BT_WIFI_COEX_STATE,*PBT_WIFI_COEX_STATE; +typedef enum _BT_ANT_TYPE{ + BTC_ANT_TYPE_0, + BTC_ANT_TYPE_1, + BTC_ANT_TYPE_2, + BTC_ANT_TYPE_3, + BTC_ANT_TYPE_4, + BTC_ANT_TYPE_MAX +}BT_ANT_TYPE,*PBT_ANT_TYPE; + // defined for BFP_BTC_GET typedef enum _BTC_GET_TYPE{ // type BOOLEAN @@ -250,6 +267,7 @@ typedef enum _BTC_GET_TYPE{ BTC_GET_BL_WIFI_UNDER_B_MODE, BTC_GET_BL_EXT_SWITCH, BTC_GET_BL_WIFI_IS_IN_MP_MODE, + BTC_GET_BL_IS_ASUS_8723B, // type s4Byte BTC_GET_S4_WIFI_RSSI, @@ -268,6 +286,7 @@ typedef enum _BTC_GET_TYPE{ BTC_GET_U1_WIFI_HS_CHNL, BTC_GET_U1_MAC_PHY_MODE, BTC_GET_U1_AP_NUM, + BTC_GET_U1_ANT_TYPE, //===== for 1Ant ====== BTC_GET_U1_LPS_MODE, @@ -320,7 +339,7 @@ typedef enum _BTC_SET_TYPE{ typedef enum _BTC_DBG_DISP_TYPE{ BTC_DBG_DISP_COEX_STATISTICS = 0x0, BTC_DBG_DISP_BT_LINK_INFO = 0x1, - BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x2, + BTC_DBG_DISP_WIFI_STATUS = 0x2, BTC_DBG_DISP_MAX }BTC_DBG_DISP_TYPE,*PBTC_DBG_DISP_TYPE; @@ -489,6 +508,7 @@ typedef struct _BTC_BT_INFO{ u1Byte rssiAdjustFor1AntCoexType; BOOLEAN bPreBtCtrlAggBufSize; BOOLEAN bBtCtrlAggBufSize; + BOOLEAN bPreRejectAggPkt; BOOLEAN bRejectAggPkt; BOOLEAN bIncreaseScanDevNum; BOOLEAN bBtTxRxMask; @@ -529,6 +549,7 @@ typedef struct _BTC_STACK_INFO{ typedef struct _BTC_BT_LINK_INFO{ BOOLEAN bBtLinkExist; + BOOLEAN bBtHiPriLinkExist; BOOLEAN bScoExist; BOOLEAN bScoOnly; BOOLEAN bA2dpExist; @@ -538,11 +559,13 @@ typedef struct _BTC_BT_LINK_INFO{ BOOLEAN bPanExist; BOOLEAN bPanOnly; BOOLEAN bSlaveRole; + BOOLEAN bAclBusy; } BTC_BT_LINK_INFO, *PBTC_BT_LINK_INFO; typedef struct _BTC_STATISTICS{ u4Byte cntBind; u4Byte cntPowerOn; + u4Byte cntPreLoadFirmware; u4Byte cntInitHwConfig; u4Byte cntInitCoexDm; u4Byte cntIpsNotify; @@ -616,6 +639,10 @@ EXhalbtcoutsrc_PowerOnSetting( IN PBTC_COEXIST pBtCoexist ); VOID +EXhalbtcoutsrc_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID EXhalbtcoutsrc_InitHwConfig( IN PBTC_COEXIST pBtCoexist, IN BOOLEAN bWifiOnly @@ -695,6 +722,14 @@ EXhalbtcoutsrc_DbgControl( IN pu1Byte pData ); VOID +EXhalbtcoutsrc_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ); +VOID EXhalbtcoutsrc_StackUpdateProfileInfo( VOID ); @@ -734,5 +769,9 @@ VOID EXhalbtcoutsrc_DisplayBtCoexInfo( IN PBTC_COEXIST pBtCoexist ); +VOID +EXhalbtcoutsrc_DisplayAntIsolation( + IN PBTC_COEXIST pBtCoexist + ); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/HalPhyRf.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/HalPhyRf.c index d74846cb3047..3070e792b9f1 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/HalPhyRf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/HalPhyRf.c @@ -18,8 +18,8 @@ * ******************************************************************************/ -//#include "Mp_Precomp.h" -#include "odm_precomp.h" +#include "Mp_Precomp.h" +#include "phydm_precomp.h" #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \ @@ -161,7 +161,7 @@ ODM_TXPowerTrackingCallback_ThermalMeter( #endif #if (DM_ODM_SUPPORT_TYPE == ODM_CE) - if ( *(pDM_Odm->mp_mode) == 1) + if (pDM_Odm->mp_mode == TRUE) #endif // RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. pDM_Odm->RFCalibrateInfo.RegA24 = 0x090e1317; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/Mp_Precomp.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/Mp_Precomp.h new file mode 100755 index 000000000000..43ea006e752b --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/Mp_Precomp.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//#include +//#include "phydm_precomp.h" +//#include "../phydm_precomp.h" + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/PhyDM_Adaptivity.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/PhyDM_Adaptivity.c new file mode 100755 index 000000000000..64ed3bc57493 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/PhyDM_Adaptivity.c @@ -0,0 +1,880 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + + +VOID +Phydm_CheckAdaptivity( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY) + { + if(pDM_Odm->bAdaOn == TRUE) + { + if(pDM_Odm->DynamicLinkAdaptivity == TRUE) + { + if(pDM_Odm->bLinked && pDM_Odm->bCheck == FALSE) + { + Phydm_NHMCounterStatistics(pDM_Odm); + Phydm_CheckEnvironment(pDM_Odm); + } + else if(!pDM_Odm->bLinked) + { + pDM_Odm->bCheck = FALSE; + } + } + else + { + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); + pDM_Odm->adaptivity_flag = TRUE; + } + } + else + { + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); + pDM_Odm->adaptivity_flag = FALSE; + } + } +} + +VOID +Phydm_NHMCounterStatisticsInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + //PHY parameters initialize for ac series + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11AC+2, 0xC350); //0x990[31:16]=0xC350 Time duration for NHM unit: us, 0xc350=200ms + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC+2, 0xffff); //0x994[31:16]=0xffff th_9, th_10 + //ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff5c); //0x998=0xffffff5c th_3, th_2, th_1, th_0 + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff50); //0x998=0xffffff52 th_3, th_2, th_1, th_0 + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffffff); //0x99c=0xffffffff th_7, th_6, th_5, th_4 + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH8_11AC, bMaskByte0, 0xff); //0x9a0[7:0]=0xff th_8 + //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT8|BIT9|BIT10, 0x7); //0x994[9:8]=3 enable CCX + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT8|BIT9|BIT10, 0x1); //0x994[10:8]=1 ignoreCCA ignore PHYTXON enable CCX + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_9E8_11AC, BIT0, 0x1); //0x9e8[7]=1 max power among all RX ants + + } + else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + //PHY parameters initialize for n series + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N+2, 0xC350); //0x894[31:16]=0x0xC350 Time duration for NHM unit: us, 0xc350=200ms + //ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N+2, 0x4e20); //0x894[31:16]=0x4e20 Time duration for NHM unit: 4us, 0x4e20=80ms + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff); //0x890[31:16]=0xffff th_9, th_10 + //ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c); //0x898=0xffffff5c th_3, th_2, th_1, th_0 + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff50); //0x898=0xffffff52 th_3, th_2, th_1, th_0 + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); //0x89c=0xffffffff th_7, th_6, th_5, th_4 + ODM_SetBBReg(pDM_Odm, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff); //0xe28[7:0]=0xff th_8 + //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7); //0x890[9:8]=3 enable CCX + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x1); //0x890[10:8]=1 ignoreCCA ignore PHYTXON enable CCX + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1); //0xc0c[7]=1 max power among all RX ants + } +} + +VOID +Phydm_NHMCounterStatistics( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT)) + return; + + // Get NHM report + Phydm_GetNHMCounterStatistics(pDM_Odm); + + // Reset NHM counter + Phydm_NHMCounterStatisticsReset(pDM_Odm); +} + +VOID +Phydm_GetNHMCounterStatistics( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte value32 = 0; + + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_NHM_CNT_11AC, bMaskDWord); + else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_NHM_CNT_11N, bMaskDWord); + + pDM_Odm->NHM_cnt_0 = (u1Byte)(value32 & bMaskByte0); + pDM_Odm->NHM_cnt_1 = (u1Byte)((value32 & bMaskByte1)>>8); + +} + +VOID +Phydm_NHMCounterStatisticsReset( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT1, 0); + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT1, 1); + } + else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0); + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1); + } +} + +VOID +Phydm_NHMBBInit( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + pDM_Odm->adaptivity_flag = FALSE; + pDM_Odm->tolerance_cnt = 3; + pDM_Odm->NHMLastTxOkcnt = 0; + pDM_Odm->NHMLastRxOkcnt = 0; + pDM_Odm->NHMCurTxOkcnt = 0; + pDM_Odm->NHMCurRxOkcnt = 0; +} + +VOID +Phydm_SetEDCCAThreshold( + IN PVOID pDM_VOID, + IN s1Byte H2L, + IN s1Byte L2H +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + ODM_SetBBReg(pDM_Odm,rOFDM0_ECCAThreshold, bMaskByte0, (u1Byte)L2H); + ODM_SetBBReg(pDM_Odm,rOFDM0_ECCAThreshold, bMaskByte2, (u1Byte)H2L); + } + else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + ODM_SetBBReg(pDM_Odm, rFPGA0_XB_LSSIReadBack, bMaskByte0, (u1Byte)L2H); + ODM_SetBBReg(pDM_Odm, rFPGA0_XB_LSSIReadBack, bMaskByte1, (u1Byte)H2L); + } +} + +VOID +Phydm_SetTRxMux( + IN PVOID pDM_VOID, + IN PhyDM_Trx_MUX_Type txMode, + IN PhyDM_Trx_MUX_Type rxMode +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_RPT_FORMAT_11N, BIT3|BIT2|BIT1, txMode); // set TXmod to standby mode to remove outside noise affect + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_RPT_FORMAT_11N, BIT22|BIT21|BIT20, rxMode); // set RXmod to standby mode to remove outside noise affect + if(pDM_Odm->RFType > ODM_1T1R) + { + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_RPT_FORMAT_11N_B, BIT3|BIT2|BIT1, txMode); // set TXmod to standby mode to remove outside noise affect + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_RPT_FORMAT_11N_B, BIT22|BIT21|BIT20, rxMode); // set RXmod to standby mode to remove outside noise affect + } + } + else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + ODM_SetBBReg(pDM_Odm, ODM_REG_TRMUX_11AC, BIT11|BIT10|BIT9|BIT8, txMode); // set TXmod to standby mode to remove outside noise affect + ODM_SetBBReg(pDM_Odm, ODM_REG_TRMUX_11AC, BIT7|BIT6|BIT5|BIT4, rxMode); // set RXmod to standby mode to remove outside noise affect + if(pDM_Odm->RFType > ODM_1T1R) + { + ODM_SetBBReg(pDM_Odm, ODM_REG_TRMUX_11AC_B, BIT11|BIT10|BIT9|BIT8, txMode); // set TXmod to standby mode to remove outside noise affect + ODM_SetBBReg(pDM_Odm, ODM_REG_TRMUX_11AC_B, BIT7|BIT6|BIT5|BIT4, rxMode); // set RXmod to standby mode to remove outside noise affect + } + } + +} + +VOID +Phydm_MACEDCCAState( + IN PVOID pDM_VOID, + IN PhyDM_MACEDCCA_Type State +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(State == PhyDM_IGNORE_EDCCA) + { + ODM_SetMACReg(pDM_Odm, REG_TX_PTCL_CTRL, BIT15, 1); //ignore EDCCA reg520[15]=1 + ODM_SetMACReg(pDM_Odm, REG_RD_CTRL, BIT11, 0); //reg524[11]=0 + } + else // don't set MAC ignore EDCCA signal + { + ODM_SetMACReg(pDM_Odm, REG_TX_PTCL_CTRL, BIT15, 0); //don't ignore EDCCA reg520[15]=0 + ODM_SetMACReg(pDM_Odm, REG_RD_CTRL, BIT11, 1); //reg524[11]=1 + } + + pDM_Odm->EDCCA_enable_state = State; + + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("EDCCA enable State = %d \n", State)); + +} + +BOOLEAN +Phydm_CalNHMcnt( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte Base = 0; + + Base = pDM_Odm->NHM_cnt_0 + pDM_Odm->NHM_cnt_1; + + if(Base != 0) + { + pDM_Odm->NHM_cnt_0 = ((pDM_Odm->NHM_cnt_0) << 8) / Base; + pDM_Odm->NHM_cnt_1 = ((pDM_Odm->NHM_cnt_1) << 8) / Base; + } + if((pDM_Odm->NHM_cnt_0 - pDM_Odm->NHM_cnt_1) >= 100) + return TRUE; // clean environment + else + return FALSE; //noisy environment + +} + + +VOID +Phydm_CheckEnvironment( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + BOOLEAN isCleanEnvironment = FALSE; + u1Byte i, clean = 0; + + if(pDM_Odm->bFirstLink == TRUE) + { + pDM_Odm->adaptivity_flag = TRUE; + pDM_Odm->bFirstLink = FALSE; + return; + } + else + { + if(pDM_Odm->NHMWait < 3) // Start enter NHM after 4 NHMWait + { + pDM_Odm->NHMWait ++; + Phydm_NHMCounterStatistics(pDM_Odm); + return; + } + else + { + Phydm_NHMCounterStatistics(pDM_Odm); + isCleanEnvironment = Phydm_CalNHMcnt(pDM_Odm); + if(isCleanEnvironment == TRUE) + { + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_backup; //mode 1 + pDM_Odm->TH_EDCCA_HL_diff= pDM_Odm->TH_EDCCA_HL_diff_backup; +#endif + pDM_Odm->adaptivity_flag = TRUE; + } + else + { +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); +#else + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_mode2; // for AP mode 2 + pDM_Odm->TH_EDCCA_HL_diff= pDM_Odm->TH_EDCCA_HL_diff_mode2; +#endif + pDM_Odm->adaptivity_flag = FALSE; + } + + pDM_Odm->bFirstLink = TRUE; + pDM_Odm->bCheck = TRUE; + } + + } + + +} + + +VOID +Phydm_NHMBB( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + BOOLEAN bCleanEnvironment; + + bCleanEnvironment = Phydm_CalNHMcnt(pDM_Odm); + + pDM_Odm->NHMCurTxOkcnt = *(pDM_Odm->pNumTxBytesUnicast) - pDM_Odm->NHMLastTxOkcnt; + pDM_Odm->NHMCurRxOkcnt = *(pDM_Odm->pNumRxBytesUnicast) - pDM_Odm->NHMLastRxOkcnt; + pDM_Odm->NHMLastTxOkcnt = *(pDM_Odm->pNumTxBytesUnicast); + pDM_Odm->NHMLastRxOkcnt = *(pDM_Odm->pNumRxBytesUnicast); + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("cnt_0=%d, cnt_1=%d, bCleanEnvironment = %d, NHMCurTxOkcnt = %llu, NHMCurRxOkcnt = %llu\n", + pDM_Odm->NHM_cnt_0, pDM_Odm->NHM_cnt_1, bCleanEnvironment, pDM_Odm->NHMCurTxOkcnt, pDM_Odm->NHMCurRxOkcnt)); + + if(pDM_Odm->NHMWait < 4) // Start enter NHM after 4 NHMWait + { + pDM_Odm->NHMWait ++; + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); + } + else if ( ((pDM_Odm->NHMCurTxOkcnt>>10) > 2) && ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u8Byte)(pDM_Odm->NHMCurRxOkcnt<<2) + 1)) //Tx > 4*Rx and Tx > 2Mb possible for adaptivity test + { + if(bCleanEnvironment == TRUE || pDM_Odm->adaptivity_flag == TRUE) + { + //Enable EDCCA since it is possible running Adaptivity testing + pDM_Odm->adaptivity_flag = TRUE; + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); + pDM_Odm->tolerance_cnt = 0; +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_backup; + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_backup ; +#endif + } + else + { + if(pDM_Odm->tolerance_cnt < 3) + pDM_Odm->tolerance_cnt ++; + else + { +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_mode2; + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_mode2 ; +#else + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); +#endif + pDM_Odm->adaptivity_flag = FALSE; + } + } + } + else // TXadaptivity_flag == TRUE && bCleanEnvironment == FALSE) + { + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); + pDM_Odm->tolerance_cnt = 0; +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_backup; + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_backup ; +#endif + } +#if(DM_ODM_SUPPORT_TYPE & ODM_AP) // for repeater mode add by YuChen 2014.06.23 +#ifdef UNIVERSAL_REPEATER + else if((bCleanEnvironment == TRUE) && (pDM_Odm->VXD_bLinked) && ((pDM_Odm->NHMCurTxOkcnt>>10) > 1)) // clean environment and VXD linked and Tx TP>1Mb + { + pDM_Odm->adaptivity_flag = TRUE; + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); + pDM_Odm->tolerance_cnt = 0; + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_backup; + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_backup ; + } +#endif +#endif // for repeater mode add by YuChen 2014.06.23 + else + { + if(pDM_Odm->tolerance_cnt < 3) + pDM_Odm->tolerance_cnt ++; + else + { +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_mode2; + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_mode2 ; +#else + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); +#endif + pDM_Odm->adaptivity_flag = FALSE; + } + } + } + + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("adaptivity_flag = %d\n ", pDM_Odm->adaptivity_flag)); +} + +VOID +Phydm_SearchPwdBLowerBound( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte value32 =0; + u1Byte cnt, IGI_Pause = 0x7f, IGI_Resume = 0x20, IGI = 0x50; //IGI = 0x50 for cal EDCCA lower bound + u1Byte txEdcca1 = 0, txEdcca0 = 0; + BOOLEAN bAdjust=TRUE; + s1Byte TH_L2H_dmc, TH_H2L_dmc, IGI_target = 0x32; + s1Byte Diff; + + Phydm_SetTRxMux(pDM_Odm, PhyDM_STANDBY_MODE, PhyDM_STANDBY_MODE); + ODM_Write_DIG(pDM_Odm, IGI_Pause); + + Diff = IGI_target -(s1Byte)IGI; + TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff; + if(TH_L2H_dmc > 10) + TH_L2H_dmc = 10; + TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; + + Phydm_SetEDCCAThreshold(pDM_Odm, TH_H2L_dmc, TH_L2H_dmc); + ODM_delay_ms(5); + + while(bAdjust) + { + for(cnt=0; cnt<20; cnt ++) + { + if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + value32 = ODM_GetBBReg(pDM_Odm,ODM_REG_RPT_11N, bMaskDWord); + else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + value32 = ODM_GetBBReg(pDM_Odm,ODM_REG_RPT_11AC, bMaskDWord); + + if (value32 & BIT30 && (pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8723B|ODM_RTL8188E))) + txEdcca1 = txEdcca1 + 1; + else if(value32 & BIT29) + txEdcca1 = txEdcca1 + 1; + else + txEdcca0 = txEdcca0 + 1; + } + + if(txEdcca1 > 9 ) + { + IGI = IGI -1; + TH_L2H_dmc = TH_L2H_dmc + 1; + if(TH_L2H_dmc > 10) + TH_L2H_dmc = 10; + TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; + + Phydm_SetEDCCAThreshold(pDM_Odm, TH_H2L_dmc, TH_L2H_dmc); + + txEdcca1 = 0; + txEdcca0 = 0; + + if(TH_L2H_dmc == 10) + { + bAdjust = FALSE; + pDM_Odm->H2L_lb = TH_H2L_dmc; + pDM_Odm->L2H_lb = TH_L2H_dmc; + pDM_Odm->Adaptivity_IGI_upper = IGI; + } + } + else + { + bAdjust = FALSE; + pDM_Odm->H2L_lb = TH_H2L_dmc; + pDM_Odm->L2H_lb = TH_L2H_dmc; + pDM_Odm->Adaptivity_IGI_upper = IGI; + } + } + + Phydm_SetTRxMux(pDM_Odm, PhyDM_TX_MODE, PhyDM_RX_MODE); + ODM_Write_DIG(pDM_Odm, IGI_Resume); + Phydm_SetEDCCAThreshold(pDM_Odm, 0x7f, 0x7f); // resume to no link state +} + +VOID +Phydm_AdaptivityInit( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if(DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER pAdapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); + pDM_Odm->Carrier_Sense_enable = (BOOLEAN)pMgntInfo->RegEnableCarrierSense; + pDM_Odm->NHM_enable = (BOOLEAN)pMgntInfo->RegNHMEnable; + pDM_Odm->DynamicLinkAdaptivity = (BOOLEAN)pMgntInfo->RegDmLinkAdaptivity; +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + pDM_Odm->Carrier_Sense_enable = (pDM_Odm->Adapter->registrypriv.adaptivity_mode!=0)?TRUE:FALSE; + pDM_Odm->NHM_enable = (BOOLEAN)pDM_Odm->Adapter->registrypriv.nhm_en; + pDM_Odm->DynamicLinkAdaptivity = FALSE; // Jeff please add this +#endif + +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + + if(pDM_Odm->Carrier_Sense_enable == FALSE) + { +#if(DM_ODM_SUPPORT_TYPE == ODM_WIN) + if( pMgntInfo->RegL2HForAdaptivity != 0 ) + pDM_Odm->TH_L2H_ini = pMgntInfo->RegL2HForAdaptivity; + else +#endif + pDM_Odm->TH_L2H_ini = 0xf5; // -7 + } + else + { +#if(DM_ODM_SUPPORT_TYPE == ODM_WIN) + if( pMgntInfo->RegL2HForAdaptivity != 0 ) + pDM_Odm->TH_L2H_ini = pMgntInfo->RegL2HForAdaptivity; + else +#endif + pDM_Odm->TH_L2H_ini = 0xa; + } + + pDM_Odm->AdapEn_RSSI = 20; + +#if(DM_ODM_SUPPORT_TYPE == ODM_WIN) + if( pMgntInfo->RegHLDiffForAdaptivity != 0 ) + pDM_Odm->TH_EDCCA_HL_diff = pMgntInfo->RegHLDiffForAdaptivity; + else +#endif + pDM_Odm->TH_EDCCA_HL_diff = 7; + + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("TH_L2H_ini = 0x%x, TH_EDCCA_HL_diff = 0x%x\n", pDM_Odm->TH_L2H_ini, pDM_Odm->TH_EDCCA_HL_diff)); + +#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + + if(pDM_Odm->Carrier_Sense_enable){ + pDM_Odm->TH_L2H_ini = 10; + pDM_Odm->TH_EDCCA_HL_diff = 7; + pDM_Odm->AdapEn_RSSI = 30; + } + else + { + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_backup; //set by mib + pDM_Odm->TH_EDCCA_HL_diff = 7; + pDM_Odm->AdapEn_RSSI = 20; + } + + pDM_Odm->TH_L2H_ini_mode2 = 20; + pDM_Odm->TH_EDCCA_HL_diff_mode2 = 8; + //pDM_Odm->TH_L2H_ini_backup = pDM_Odm->TH_L2H_ini; + pDM_Odm->TH_EDCCA_HL_diff_backup = pDM_Odm->TH_EDCCA_HL_diff ; + if(priv->pshare->rf_ft_var.adaptivity_enable == 2) + pDM_Odm->DynamicLinkAdaptivity = TRUE; + else + pDM_Odm->DynamicLinkAdaptivity = FALSE; +// pDM_Odm->NHM_enable = FALSE; +#endif + + pDM_Odm->IGI_Base = 0x32; + pDM_Odm->IGI_target = 0x1c; + pDM_Odm->ForceEDCCA = 0; + pDM_Odm->H2L_lb= 0; + pDM_Odm->L2H_lb= 0; + pDM_Odm->Adaptivity_IGI_upper = 0; + pDM_Odm->NHMWait = 0; + Phydm_NHMBBInit(pDM_Odm); + pDM_Odm->bCheck = FALSE; + pDM_Odm->bFirstLink = TRUE; + pDM_Odm->bAdaOn = TRUE; + + ODM_SetBBReg(pDM_Odm, REG_RD_CTRL, BIT11, 1); // stop counting if EDCCA is asserted + + //Search pwdB lower bound + { + if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + ODM_SetBBReg(pDM_Odm,ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208); + else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + ODM_SetBBReg(pDM_Odm,ODM_REG_DBG_RPT_11AC, bMaskDWord, 0x209); + Phydm_SearchPwdBLowerBound(pDM_Odm); + } + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); +} + + +BOOLEAN +Phydm_Adaptivity( + IN PVOID pDM_VOID, + IN u1Byte IGI +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + s1Byte TH_L2H_dmc, TH_H2L_dmc, L2H_nolink_Band4 = 0x7f, H2L_nolink_Band4 = 0x7f; + s1Byte Diff, IGI_target; + BOOLEAN EDCCA_State = FALSE; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER pAdapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + BOOLEAN bFwCurrentInPSMode=FALSE; + PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_FW_PSMODE_STATUS, (pu1Byte)(&bFwCurrentInPSMode)); + + // Disable EDCCA mode while under LPS mode, added by Roger, 2012.09.14. + if(bFwCurrentInPSMode) + return FALSE; +#endif + + if(!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("Go to odm_DynamicEDCCA() \n")); + // Add by Neil Chen to enable edcca to MP Platform +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + // Adjust EDCCA. + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + Phydm_DynamicEDCCA(pDM_Odm); +#endif + return FALSE; + } + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if(pMgntInfo->RegEnableAdaptivity== 2) +#else + if (pDM_Odm->Adapter->registrypriv.adaptivity_en == 2) +#endif + { + if(pDM_Odm->Carrier_Sense_enable == FALSE) // check domain Code for Adaptivity or CarrierSense + { + if ((*pDM_Odm->pBandType == ODM_BAND_5G) && + !(pDM_Odm->odm_Regulation5G == REGULATION_ETSI || pDM_Odm->odm_Regulation5G == REGULATION_WW)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("Adaptivity skip 5G domain code : %d \n", pDM_Odm->odm_Regulation5G)); + return FALSE; + } + + else if((*pDM_Odm->pBandType == ODM_BAND_2_4G) && + !(pDM_Odm->odm_Regulation2_4G == REGULATION_ETSI || pDM_Odm->odm_Regulation2_4G == REGULATION_WW)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("Adaptivity skip 2.4G domain code : %d \n", pDM_Odm->odm_Regulation2_4G)); + return FALSE; + + } + else if ((*pDM_Odm->pBandType != ODM_BAND_2_4G) && (*pDM_Odm->pBandType != ODM_BAND_5G)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("Adaptivity neither 2G nor 5G band, return\n")); + return FALSE; + } + } + else + { + if ((*pDM_Odm->pBandType == ODM_BAND_5G) && + !(pDM_Odm->odm_Regulation5G == REGULATION_ETSI || pDM_Odm->odm_Regulation5G == REGULATION_WW)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("CarrierSense skip 5G domain code : %d\n", pDM_Odm->odm_Regulation5G)); + return FALSE; + } + + else if((*pDM_Odm->pBandType == ODM_BAND_2_4G) && + !(pDM_Odm->odm_Regulation2_4G == REGULATION_ETSI || pDM_Odm->odm_Regulation2_4G == REGULATION_WW)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("CarrierSense skip 2.4G domain code : %d\n", pDM_Odm->odm_Regulation2_4G)); + return FALSE; + + } + else if ((*pDM_Odm->pBandType != ODM_BAND_2_4G) && (*pDM_Odm->pBandType != ODM_BAND_5G)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("CarrierSense neither 2G nor 5G band, return\n")); + return FALSE; + } + } + } +#endif + + + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("odm_Adaptivity() =====> \n")); + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("ForceEDCCA=%d, IGI_Base=0x%x, TH_L2H_ini = %d, TH_EDCCA_HL_diff = %d, AdapEn_RSSI = %d\n", + pDM_Odm->ForceEDCCA, pDM_Odm->IGI_Base, pDM_Odm->TH_L2H_ini, pDM_Odm->TH_EDCCA_HL_diff, pDM_Odm->AdapEn_RSSI)); + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + ODM_SetBBReg(pDM_Odm, 0x800, BIT10, 0); //ADC_mask enable + + if(*pDM_Odm->pBandWidth == ODM_BW20M) //CHANNEL_WIDTH_20 + IGI_target = pDM_Odm->IGI_Base; + else if(*pDM_Odm->pBandWidth == ODM_BW40M) + IGI_target = pDM_Odm->IGI_Base + 2; + else if(*pDM_Odm->pBandWidth == ODM_BW80M) + IGI_target = pDM_Odm->IGI_Base + 2; + else + IGI_target = pDM_Odm->IGI_Base; + pDM_Odm->IGI_target = (u1Byte) IGI_target; + + if(*pDM_Odm->pChannel >= 149) // Band4 -> for AP : mode2, for sd4 and sd7 : turnoff adaptivity + { +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + if(pDM_Odm->bLinked) + { + Diff = IGI_target -(s1Byte)IGI; + L2H_nolink_Band4 = pDM_Odm->TH_L2H_ini_mode2 + Diff; + if(L2H_nolink_Band4 > 10) + L2H_nolink_Band4 = 10; + H2L_nolink_Band4 = L2H_nolink_Band4 - pDM_Odm->TH_EDCCA_HL_diff_mode2; + } +#endif + Phydm_SetEDCCAThreshold(pDM_Odm, H2L_nolink_Band4, L2H_nolink_Band4); + return FALSE; + } + + if(!pDM_Odm->ForceEDCCA) + { + if(pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI) + EDCCA_State = 1; + else if(pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5)) + EDCCA_State = 0; + } + else + EDCCA_State = 1; + + if(pDM_Odm->Carrier_Sense_enable == FALSE && pDM_Odm->NHM_enable == TRUE) + Phydm_NHMBB(pDM_Odm); + + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("BandWidth=%s, IGI_target=0x%x, EDCCA_State=%d, EDCCA_enable_state = %d\n", + (*pDM_Odm->pBandWidth==ODM_BW80M)?"80M":((*pDM_Odm->pBandWidth==ODM_BW40M)?"40M":"20M"), IGI_target, EDCCA_State, pDM_Odm->EDCCA_enable_state)); + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("RSSI_min = %d, AdapIGIUpper= 0x %x\n", pDM_Odm->RSSI_Min, pDM_Odm->Adaptivity_IGI_upper)); + + + if(EDCCA_State == 1) + { + Diff = IGI_target -(s1Byte)IGI; + TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff; + if(TH_L2H_dmc > 10) + TH_L2H_dmc = 10; + + TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; + + //replace lower bound to prevent EDCCA always equal 1 + if(TH_H2L_dmc < pDM_Odm->H2L_lb) + TH_H2L_dmc = pDM_Odm->H2L_lb; + if(TH_L2H_dmc < pDM_Odm->L2H_lb) + TH_L2H_dmc = pDM_Odm->L2H_lb; + } + else + { + TH_L2H_dmc = 0x7f; + TH_H2L_dmc = 0x7f; + } + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("IGI=0x%x, TH_L2H_dmc = %d, TH_H2L_dmc = %d, adaptivity_flg = %d, bAdaOn = %d, DynamicLinkAdaptivity = %d, NHM_enable = %d\n", + IGI, TH_L2H_dmc, TH_H2L_dmc, pDM_Odm->adaptivity_flag, pDM_Odm->bAdaOn, pDM_Odm->DynamicLinkAdaptivity, pDM_Odm->NHM_enable)); + + Phydm_SetEDCCAThreshold(pDM_Odm, TH_H2L_dmc, TH_L2H_dmc); + return TRUE; +} + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +Phydm_EnableEDCCA( + IN PVOID pDM_VOID +) +{ + + // This should be moved out of OUTSRC + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER pAdapter = pDM_Odm->Adapter; + // Enable EDCCA. The value is suggested by SD3 Wilson. + + // + // Revised for ASUS 11b/g performance issues, suggested by BB Neil, 2012.04.13. + // + if((pDM_Odm->SupportICType == ODM_RTL8723A)&&(IS_WIRELESS_MODE_G(pAdapter))) + { + //PlatformEFIOWrite1Byte(Adapter, rOFDM0_ECCAThreshold, 0x00); + ODM_Write1Byte(pDM_Odm,rOFDM0_ECCAThreshold,0x00); + ODM_Write1Byte(pDM_Odm,rOFDM0_ECCAThreshold+2,0xFD); + + } + else + { + //PlatformEFIOWrite1Byte(Adapter, rOFDM0_ECCAThreshold, 0x03); + ODM_Write1Byte(pDM_Odm,rOFDM0_ECCAThreshold,0x03); + ODM_Write1Byte(pDM_Odm,rOFDM0_ECCAThreshold+2,0x00); + } + + //PlatformEFIOWrite1Byte(Adapter, rOFDM0_ECCAThreshold+2, 0x00); +} + +VOID +Phydm_DisableEDCCA( + IN PVOID pDM_VOID +) +{ + // Disable EDCCA.. + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + ODM_Write1Byte(pDM_Odm, rOFDM0_ECCAThreshold, 0x7f); + ODM_Write1Byte(pDM_Odm, rOFDM0_ECCAThreshold+2, 0x7f); +} + +// +// Description: According to initial gain value to determine to enable or disable EDCCA. +// +// Suggested by SD3 Wilson. Added by tynli. 2011.11.25. +// +VOID +Phydm_DynamicEDCCA( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER pAdapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u1Byte RegC50, RegC58; + BOOLEAN bEDCCAenable = FALSE; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + BOOLEAN bFwCurrentInPSMode=FALSE; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_FW_PSMODE_STATUS, (pu1Byte)(&bFwCurrentInPSMode)); + + // Disable EDCCA mode while under LPS mode, added by Roger, 2012.09.14. + if(bFwCurrentInPSMode) + return; +#endif + // + // 2013/11/14 Ken According to BB team Jame's suggestion, we need to disable soft AP mode EDCCA. + // 2014/01/08 MH For Miracst AP mode test. We need to disable EDCCA. Otherwise, we may stop + // to send beacon in noisy environment or platform. + // + if(ACTING_AS_AP(pAdapter) || ACTING_AS_AP(GetFirstAPAdapter(pAdapter))) + //if(ACTING_AS_AP(pAdapter)) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("At least One Port as AP disable EDCCA\n")); + Phydm_DisableEDCCA(pDM_Odm); + if(pHalData->bPreEdccaEnable) + Phydm_DisableEDCCA(pDM_Odm); + pHalData->bPreEdccaEnable = FALSE; + return; + } + + RegC50 = (u1Byte)ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0); + RegC58 = (u1Byte)ODM_GetBBReg(pDM_Odm, rOFDM0_XBAGCCore1, bMaskByte0); + + + if((RegC50 > 0x28 && RegC58 > 0x28) || + ((pDM_Odm->SupportICType == ODM_RTL8723A && IS_WIRELESS_MODE_G(pAdapter) && RegC50>0x26)) || + (pDM_Odm->SupportICType == ODM_RTL8188E && RegC50 > 0x28)) + { + if(!pHalData->bPreEdccaEnable) + { + Phydm_EnableEDCCA(pDM_Odm); + pHalData->bPreEdccaEnable = TRUE; + } + + } + else if((RegC50 < 0x25 && RegC58 < 0x25) || (pDM_Odm->SupportICType == ODM_RTL8188E && RegC50 < 0x25)) + { + if(pHalData->bPreEdccaEnable) + { + Phydm_DisableEDCCA(pDM_Odm); + pHalData->bPreEdccaEnable = FALSE; + } + } +} + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/PhyDM_Adaptivity.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/PhyDM_Adaptivity.h new file mode 100755 index 000000000000..e586ac8cf3a7 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/PhyDM_Adaptivity.h @@ -0,0 +1,146 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMADAPTIVITY_H__ +#define __PHYDMADAPTIVITY_H__ + +#define ADAPTIVITY_VERSION "7.1" + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +typedef enum _tag_PhyDM_REGULATION_Type { + REGULATION_FCC = 0, + REGULATION_MKK = 1, + REGULATION_ETSI = 2, + REGULATION_WW = 3, + + MAX_REGULATION_NUM = 4 +} PhyDM_REGULATION_TYPE; +#endif + +typedef enum tag_PhyDM_TRx_MUX_Type +{ + PhyDM_SHUTDOWN = 0, + PhyDM_STANDBY_MODE = 1, + PhyDM_TX_MODE = 2, + PhyDM_RX_MODE = 3 +}PhyDM_Trx_MUX_Type; + +typedef enum tag_PhyDM_MACEDCCA_Type +{ + PhyDM_IGNORE_EDCCA = 0, + PhyDM_DONT_IGNORE_EDCCA = 1 +}PhyDM_MACEDCCA_Type; + + +VOID +Phydm_CheckAdaptivity( + IN PVOID pDM_VOID + ); + +VOID +Phydm_CheckEnvironment( + IN PVOID pDM_VOID + ); + +VOID +Phydm_NHMCounterStatisticsInit( + IN PVOID pDM_VOID + ); + +VOID +Phydm_NHMCounterStatistics( + IN PVOID pDM_VOID + ); + +VOID +Phydm_NHMBBInit( + IN PVOID pDM_VOID +); + +VOID +Phydm_NHMBB( + IN PVOID pDM_VOID +); + +VOID +Phydm_NHMCounterStatisticsReset( + IN PVOID pDM_VOID +); + +VOID +Phydm_GetNHMCounterStatistics( + IN PVOID pDM_VOID +); + +VOID +Phydm_MACEDCCAState( + IN PVOID pDM_VOID, + IN PhyDM_MACEDCCA_Type State +); + +VOID +Phydm_SetEDCCAThreshold( + IN PVOID pDM_VOID, + IN s1Byte H2L, + IN s1Byte L2H +); + +VOID +Phydm_SetTRxMux( + IN PVOID pDM_VOID, + IN PhyDM_Trx_MUX_Type txMode, + IN PhyDM_Trx_MUX_Type rxMode +); + +BOOLEAN +Phydm_CalNHMcnt( + IN PVOID pDM_VOID +); + +VOID +Phydm_SearchPwdBLowerBound( + IN PVOID pDM_VOID +); + +VOID +Phydm_AdaptivityInit( + IN PVOID pDM_VOID + ); + +BOOLEAN +Phydm_Adaptivity( + IN PVOID pDM_VOID, + IN u1Byte IGI + ); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +Phydm_DisableEDCCA( + IN PVOID pDM_VOID +); + +VOID +Phydm_DynamicEDCCA( + IN PVOID pDM_VOID +); +#endif + + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm.c new file mode 100755 index 000000000000..13e5e28ec647 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm.c @@ -0,0 +1,2397 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ + +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + + +const u2Byte dB_Invert_Table[8][12] = { + { 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4}, + { 4, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16}, + { 18, 20, 22, 25, 28, 32, 35, 40, 45, 50, 56, 63}, + { 71, 79, 89, 100, 112, 126, 141, 158, 178, 200, 224, 251}, + { 282, 316, 355, 398, 447, 501, 562, 631, 708, 794, 891, 1000}, + { 1122, 1259, 1413, 1585, 1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981}, + { 4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000, 11220, 12589, 14125, 15849}, + { 17783, 19953, 22387, 25119, 28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535}}; + + +//============================================================ +// Local Function predefine. +//============================================================ + +VOID +odm_SwAntDetectInit( + IN PDM_ODM_T pDM_Odm + ); + + + + + +VOID +odm_AntennaDiversityInit( + IN PDM_ODM_T pDM_Odm +); + +VOID +odm_AntennaDiversity( + IN PDM_ODM_T pDM_Odm +); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_UpdateInitRateWorkItemCallback( + IN PVOID pContext + ); +#endif + + +VOID +odm_GlobalAdapterCheck( + IN VOID + ); + +//Remove RAMask by RS_James + + + +VOID +odm_IQCalibrate( + IN PDM_ODM_T pDM_Odm + ); + +//remove PT by Yuchen + +//Remove Edca by Yu Chen + + +VOID +odm_UpdatePowerTrainingState( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_AsocEntry_Init( + IN PDM_ODM_T pDM_Odm + ); + +//============================================================ +//3 Export Interface +//============================================================ + +VOID +ODM_InitMpDriverStatus( + IN PDM_ODM_T pDM_Odm +) +{ +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + + // Decide when compile time + #if(MP_DRIVER == 1) + pDM_Odm->mp_mode = TRUE; + #else + pDM_Odm->mp_mode = FALSE; + #endif + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + + PADAPTER Adapter = pDM_Odm->Adapter; + + // Update information every period + pDM_Odm->mp_mode = (BOOLEAN)Adapter->registrypriv.mp_mode; + +#else + + // MP mode is always false at AP side + pDM_Odm->mp_mode = FALSE; + +#endif +} + +VOID +ODM_UpdateMpDriverStatus( + IN PDM_ODM_T pDM_Odm +) +{ +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + + // Do nothing. + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + + // Update information erery period + pDM_Odm->mp_mode = (BOOLEAN)Adapter->registrypriv.mp_mode; + +#else + + // Do nothing. + +#endif +} + +VOID +odm_CommonInfoSelfInit( + IN PDM_ODM_T pDM_Odm + ) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + pDM_Odm->bCckHighPower = (BOOLEAN) ODM_GetBBReg(pDM_Odm, ODM_REG(CCK_RPT_FORMAT,pDM_Odm), ODM_BIT(CCK_RPT_FORMAT,pDM_Odm)); + pDM_Odm->RFPathRxEnable = (u1Byte) ODM_GetBBReg(pDM_Odm, ODM_REG(BB_RX_PATH,pDM_Odm), ODM_BIT(BB_RX_PATH,pDM_Odm)); +#if (DM_ODM_SUPPORT_TYPE != ODM_CE) + pDM_Odm->pbNet_closed = &pDM_Odm->BOOLEAN_temp; +#endif + + PHYDM_InitDebugSetting(pDM_Odm); + ODM_InitMpDriverStatus(pDM_Odm); + + pDM_Odm->TxRate = 0xFF; + +} + +VOID +odm_CommonInfoSelfUpdate( + IN PDM_ODM_T pDM_Odm + ) +{ + u1Byte EntryCnt=0; + u1Byte i; + PSTA_INFO_T pEntry; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + pEntry = pDM_Odm->pODM_StaInfo[0]; + if(pMgntInfo->mAssoc) + { + pEntry->bUsed=TRUE; + for (i=0; i<6; i++) + pEntry->MacAddr[i] = pMgntInfo->Bssid[i]; + } + else + { + pEntry->bUsed=FALSE; + for (i=0; i<6; i++) + pEntry->MacAddr[i] = 0; + } + + //STA mode is linked to AP + if(IS_STA_VALID(pDM_Odm->pODM_StaInfo[0]) && !ACTING_AS_AP(Adapter)) + pDM_Odm->bsta_state = TRUE; + else + pDM_Odm->bsta_state = FALSE; +#endif + + + if(*(pDM_Odm->pBandWidth) == ODM_BW40M) + { + if(*(pDM_Odm->pSecChOffset) == 1) + pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) -2; + else if(*(pDM_Odm->pSecChOffset) == 2) + pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) +2; + } + else + pDM_Odm->ControlChannel = *(pDM_Odm->pChannel); + + for (i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pEntry)) + EntryCnt++; + } + + if(EntryCnt == 1) + pDM_Odm->bOneEntryOnly = TRUE; + else + pDM_Odm->bOneEntryOnly = FALSE; + + // Update MP driver status + ODM_UpdateMpDriverStatus(pDM_Odm); +} + +VOID +odm_CommonInfoSelfReset( + IN PDM_ODM_T pDM_Odm + ) +{ +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pDM_Odm->PhyDbgInfo.NumQryBeaconPkt = 0; +#endif +} + +PVOID +PhyDM_Get_Structure( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Structure_Type +) + +{ + PVOID pStruct = NULL; +#if RTL8195A_SUPPORT + switch (Structure_Type){ + case PHYDM_FALSEALMCNT: + pStruct = &FalseAlmCnt; + break; + + case PHYDM_CFOTRACK: + pStruct = &DM_CfoTrack; + break; + + default: + break; + } + +#else + switch (Structure_Type){ + case PHYDM_FALSEALMCNT: + pStruct = &(pDM_Odm->FalseAlmCnt); + break; + + case PHYDM_CFOTRACK: + pStruct = &(pDM_Odm->DM_CfoTrack); + break; + + default: + break; + } + +#endif + return pStruct; +} + +VOID +odm_HWSetting( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (RTL8821A_SUPPORT == 1) + if(pDM_Odm->SupportICType & ODM_RTL8821) + odm_HWSetting_8821A(pDM_Odm); +#endif + +} + +// +// 2011/09/21 MH Add to describe different team necessary resource allocate?? +// +VOID +ODM_DMInit( + IN PDM_ODM_T pDM_Odm + ) +{ + + odm_CommonInfoSelfInit(pDM_Odm); + odm_DIGInit(pDM_Odm); + Phydm_NHMCounterStatisticsInit(pDM_Odm); + Phydm_AdaptivityInit(pDM_Odm); + odm_RateAdaptiveMaskInit(pDM_Odm); + ODM_CfoTrackingInit(pDM_Odm); + ODM_EdcaTurboInit(pDM_Odm); + odm_RSSIMonitorInit(pDM_Odm); + odm_TXPowerTrackingInit(pDM_Odm); + odm_AntennaDiversityInit(pDM_Odm); + odm_AutoChannelSelectInit(pDM_Odm); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + ODM_ClearTxPowerTrackingState(pDM_Odm); + odm_PathDiversityInit(pDM_Odm); +#endif + + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + odm_DynamicBBPowerSavingInit(pDM_Odm); + odm_DynamicTxPowerInit(pDM_Odm); + +#if (RTL8188E_SUPPORT == 1) + if(pDM_Odm->SupportICType==ODM_RTL8188E) + { + odm_PrimaryCCA_Init(pDM_Odm); + ODM_RAInfo_Init_all(pDM_Odm); + } +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + + #if (RTL8723B_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8723B) + odm_SwAntDetectInit(pDM_Odm); + #endif + + #if (RTL8192E_SUPPORT == 1) + if(pDM_Odm->SupportICType==ODM_RTL8192E) + odm_PrimaryCCA_Check_Init(pDM_Odm); + #endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if (RTL8723A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8723A) + odm_PSDMonitorInit(pDM_Odm); + #endif + + #if (RTL8192D_SUPPORT == 1) + if(pDM_Odm->SupportICType==ODM_RTL8192D) + odm_PathDivInit_92D(pDM_Odm); + #endif + + #if ((RTL8192C_SUPPORT == 1) || (RTL8192D_SUPPORT == 1)) + if(pDM_Odm->SupportICType & (ODM_RTL8192C|ODM_RTL8192D)) + odm_RXHPInit(pDM_Odm); + #endif +#endif +#endif + + } + +} + +VOID +ODM_DMReset( + IN PDM_ODM_T pDM_Odm + ) +{ + #if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) + ODM_AntDivReset(pDM_Odm); + #endif +} + +// +// 2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. +// You can not add any dummy function here, be care, you can only use DM structure +// to perform any new ODM_DM. +// +VOID +ODM_DMWatchdog( + IN PDM_ODM_T pDM_Odm + ) +{ + ODM_AsocEntry_Init(pDM_Odm); + odm_CommonInfoSelfUpdate(pDM_Odm); + phydm_BasicDbgMessage(pDM_Odm); + odm_HWSetting(pDM_Odm); + odm_FalseAlarmCounterStatistics(pDM_Odm); + odm_RSSIMonitorCheck(pDM_Odm); + + if(*(pDM_Odm->pbPowerSaving) == TRUE) + { + odm_DIGbyRSSI_LPS(pDM_Odm); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("DMWatchdog in power saving mode\n")); + return; + } + + Phydm_CheckAdaptivity(pDM_Odm); + odm_UpdatePowerTrainingState(pDM_Odm); + odm_DIG(pDM_Odm); + { + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + pDM_Odm->bAdaOn = Phydm_Adaptivity(pDM_Odm, pDM_DigTable->CurIGValue); + } + odm_CCKPacketDetectionThresh(pDM_Odm); + odm_RefreshRateAdaptiveMask(pDM_Odm); + odm_RefreshBasicRateMask(pDM_Odm); + odm_DynamicBBPowerSaving(pDM_Odm); + odm_EdcaTurboCheck(pDM_Odm); + odm_PathDiversity(pDM_Odm); + ODM_CfoTracking(pDM_Odm); + odm_DynamicTxPower(pDM_Odm); + odm_AntennaDiversity(pDM_Odm); + +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + + ODM_TXPowerTrackingCheck(pDM_Odm); + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + odm_IQCalibrate(pDM_Odm); + else +#endif + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { +#if (RTL8192D_SUPPORT == 1) + if(pDM_Odm->SupportICType==ODM_RTL8192D) + ODM_DynamicEarlyMode(pDM_Odm); +#endif + +#if (RTL8188E_SUPPORT == 1) + if(pDM_Odm->SupportICType==ODM_RTL8188E) + odm_DynamicPrimaryCCA(pDM_Odm); +#endif + +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + + #if (RTL8192E_SUPPORT == 1) + if(pDM_Odm->SupportICType==ODM_RTL8192E) + odm_DynamicPrimaryCCA_Check(pDM_Odm); + #endif + +#if( DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if ((RTL8192C_SUPPORT == 1) || (RTL8192D_SUPPORT == 1)) + if(pDM_Odm->SupportICType & (ODM_RTL8192C|ODM_RTL8192D)) + odm_RXHP(pDM_Odm); + #endif +#endif +#endif + } + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + odm_dtc(pDM_Odm); +#endif + + odm_CommonInfoSelfReset(pDM_Odm); + +} + + +// +// Init /.. Fixed HW value. Only init time. +// +VOID +ODM_CmnInfoInit( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN u4Byte Value + ) +{ + // + // This section is used for init value + // + switch (CmnInfo) + { + // + // Fixed ODM value. + // + case ODM_CMNINFO_ABILITY: + pDM_Odm->SupportAbility = (u4Byte)Value; + break; + + case ODM_CMNINFO_RF_TYPE: + pDM_Odm->RFType = (u1Byte)Value; + break; + + case ODM_CMNINFO_PLATFORM: + pDM_Odm->SupportPlatform = (u1Byte)Value; + break; + + case ODM_CMNINFO_INTERFACE: + pDM_Odm->SupportInterface = (u1Byte)Value; + break; + + case ODM_CMNINFO_MP_TEST_CHIP: + pDM_Odm->bIsMPChip= (u1Byte)Value; + break; + + case ODM_CMNINFO_IC_TYPE: + pDM_Odm->SupportICType = Value; + break; + + case ODM_CMNINFO_CUT_VER: + pDM_Odm->CutVersion = (u1Byte)Value; + break; + + case ODM_CMNINFO_FAB_VER: + pDM_Odm->FabVersion = (u1Byte)Value; + break; + + case ODM_CMNINFO_RFE_TYPE: + pDM_Odm->RFEType = (u1Byte)Value; + break; + + case ODM_CMNINFO_RF_ANTENNA_TYPE: + pDM_Odm->AntDivType= (u1Byte)Value; + break; + + case ODM_CMNINFO_BOARD_TYPE: + pDM_Odm->BoardType = (u1Byte)Value; + break; + + case ODM_CMNINFO_PACKAGE_TYPE: + pDM_Odm->PackageType = (u1Byte)Value; + break; + + case ODM_CMNINFO_EXT_LNA: + pDM_Odm->ExtLNA = (u1Byte)Value; + break; + + case ODM_CMNINFO_5G_EXT_LNA: + pDM_Odm->ExtLNA5G = (u1Byte)Value; + break; + + case ODM_CMNINFO_EXT_PA: + pDM_Odm->ExtPA = (u1Byte)Value; + break; + + case ODM_CMNINFO_5G_EXT_PA: + pDM_Odm->ExtPA5G = (u1Byte)Value; + break; + + case ODM_CMNINFO_GPA: + pDM_Odm->TypeGPA= (ODM_TYPE_GPA_E)Value; + break; + case ODM_CMNINFO_APA: + pDM_Odm->TypeAPA= (ODM_TYPE_APA_E)Value; + break; + case ODM_CMNINFO_GLNA: + pDM_Odm->TypeGLNA= (ODM_TYPE_GLNA_E)Value; + break; + case ODM_CMNINFO_ALNA: + pDM_Odm->TypeALNA= (ODM_TYPE_ALNA_E)Value; + break; + + case ODM_CMNINFO_EXT_TRSW: + pDM_Odm->ExtTRSW = (u1Byte)Value; + break; + case ODM_CMNINFO_PATCH_ID: + pDM_Odm->PatchID = (u1Byte)Value; + break; + case ODM_CMNINFO_BINHCT_TEST: + pDM_Odm->bInHctTest = (BOOLEAN)Value; + break; + case ODM_CMNINFO_BWIFI_TEST: + pDM_Odm->bWIFITest = (BOOLEAN)Value; + break; + case ODM_CMNINFO_SMART_CONCURRENT: + pDM_Odm->bDualMacSmartConcurrent = (BOOLEAN )Value; + break; + case ODM_CMNINFO_DOMAIN_CODE_2G: + pDM_Odm->odm_Regulation2_4G = (u1Byte)Value; + break; + case ODM_CMNINFO_DOMAIN_CODE_5G: + pDM_Odm->odm_Regulation5G = (u1Byte)Value; + break; + case ODM_CMNINFO_IQKFWOFFLOAD: + pDM_Odm->IQKFWOffload = (u1Byte)Value; + break; + //To remove the compiler warning, must add an empty default statement to handle the other values. + default: + //do nothing + break; + + } + +} + + +VOID +ODM_CmnInfoHook( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN PVOID pValue + ) +{ + // + // Hook call by reference pointer. + // + switch (CmnInfo) + { + // + // Dynamic call by reference pointer. + // + case ODM_CMNINFO_MAC_PHY_MODE: + pDM_Odm->pMacPhyMode = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_TX_UNI: + pDM_Odm->pNumTxBytesUnicast = (u8Byte *)pValue; + break; + + case ODM_CMNINFO_RX_UNI: + pDM_Odm->pNumRxBytesUnicast = (u8Byte *)pValue; + break; + + case ODM_CMNINFO_WM_MODE: + pDM_Odm->pWirelessMode = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_BAND: + pDM_Odm->pBandType = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_SEC_CHNL_OFFSET: + pDM_Odm->pSecChOffset = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_SEC_MODE: + pDM_Odm->pSecurity = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_BW: + pDM_Odm->pBandWidth = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_CHNL: + pDM_Odm->pChannel = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_DMSP_GET_VALUE: + pDM_Odm->pbGetValueFromOtherMac = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_BUDDY_ADAPTOR: + pDM_Odm->pBuddyAdapter = (PADAPTER *)pValue; + break; + + case ODM_CMNINFO_DMSP_IS_MASTER: + pDM_Odm->pbMasterOfDMSP = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_SCAN: + pDM_Odm->pbScanInProcess = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_POWER_SAVING: + pDM_Odm->pbPowerSaving = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_ONE_PATH_CCA: + pDM_Odm->pOnePathCCA = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_DRV_STOP: + pDM_Odm->pbDriverStopped = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_PNP_IN: + pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_INIT_ON: + pDM_Odm->pinit_adpt_in_progress = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_ANT_TEST: + pDM_Odm->pAntennaTest = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_NET_CLOSED: + pDM_Odm->pbNet_closed = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_FORCED_RATE: + pDM_Odm->pForcedDataRate = (pu2Byte)pValue; + break; + + case ODM_CMNINFO_FORCED_IGI_LB: + pDM_Odm->pu1ForcedIgiLb = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_P2P_LINK: + pDM_Odm->DM_DigTable.pbP2pLinkInProgress = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_FCS_MODE: + pDM_Odm->pIsFcsModeEnable = (BOOLEAN *)pValue; + break; +//sd7 only + + //case ODM_CMNINFO_RTSTA_AID: + // pDM_Odm->pAidMap = (u1Byte *)pValue; + // break; + + //case ODM_CMNINFO_BT_COEXIST: + // pDM_Odm->BTCoexist = (BOOLEAN *)pValue; + + //case ODM_CMNINFO_STA_STATUS: + //pDM_Odm->pODM_StaInfo[] = (PSTA_INFO_T)pValue; + //break; + + //case ODM_CMNINFO_PHY_STATUS: + // pDM_Odm->pPhyInfo = (ODM_PHY_INFO *)pValue; + // break; + + //case ODM_CMNINFO_MAC_STATUS: + // pDM_Odm->pMacInfo = (ODM_MAC_INFO *)pValue; + // break; + //To remove the compiler warning, must add an empty default statement to handle the other values. + default: + //do nothing + break; + + } + +} + + +VOID +ODM_CmnInfoPtrArrayHook( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN u2Byte Index, + IN PVOID pValue + ) +{ + // + // Hook call by reference pointer. + // + switch (CmnInfo) + { + // + // Dynamic call by reference pointer. + // + case ODM_CMNINFO_STA_STATUS: + pDM_Odm->pODM_StaInfo[Index] = (PSTA_INFO_T)pValue; + break; + //To remove the compiler warning, must add an empty default statement to handle the other values. + default: + //do nothing + break; + } + +} + + +// +// Update Band/CHannel/.. The values are dynamic but non-per-packet. +// +VOID +ODM_CmnInfoUpdate( + IN PDM_ODM_T pDM_Odm, + IN u4Byte CmnInfo, + IN u8Byte Value + ) +{ + // + // This init variable may be changed in run time. + // + switch (CmnInfo) + { + case ODM_CMNINFO_LINK_IN_PROGRESS: + pDM_Odm->bLinkInProcess = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_ABILITY: + pDM_Odm->SupportAbility = (u4Byte)Value; + break; + + case ODM_CMNINFO_RF_TYPE: + pDM_Odm->RFType = (u1Byte)Value; + break; + + case ODM_CMNINFO_WIFI_DIRECT: + pDM_Odm->bWIFI_Direct = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_WIFI_DISPLAY: + pDM_Odm->bWIFI_Display = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_LINK: + pDM_Odm->bLinked = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_STATION_STATE: + pDM_Odm->bsta_state = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_RSSI_MIN: + pDM_Odm->RSSI_Min= (u1Byte)Value; + break; + + case ODM_CMNINFO_DBG_COMP: + pDM_Odm->DebugComponents = Value; + break; + + case ODM_CMNINFO_DBG_LEVEL: + pDM_Odm->DebugLevel = (u4Byte)Value; + break; + case ODM_CMNINFO_RA_THRESHOLD_HIGH: + pDM_Odm->RateAdaptive.HighRSSIThresh = (u1Byte)Value; + break; + + case ODM_CMNINFO_RA_THRESHOLD_LOW: + pDM_Odm->RateAdaptive.LowRSSIThresh = (u1Byte)Value; + break; + // The following is for BT HS mode and BT coexist mechanism. + case ODM_CMNINFO_BT_ENABLED: + pDM_Odm->bBtEnabled = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_BT_HS_CONNECT_PROCESS: + pDM_Odm->bBtConnectProcess = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_BT_HS_RSSI: + pDM_Odm->btHsRssi = (u1Byte)Value; + break; + + case ODM_CMNINFO_BT_OPERATION: + pDM_Odm->bBtHsOperation = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_BT_LIMITED_DIG: + pDM_Odm->bBtLimitedDig = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_BT_DISABLE_EDCA: + pDM_Odm->bBtDisableEdcaTurbo = (BOOLEAN)Value; + break; + + +#if(DM_ODM_SUPPORT_TYPE & ODM_AP) // for repeater mode add by YuChen 2014.06.23 +#ifdef UNIVERSAL_REPEATER + case ODM_CMNINFO_VXD_LINK: + pDM_Odm->VXD_bLinked= (BOOLEAN)Value; + break; +#endif +#endif +/* + case ODM_CMNINFO_OP_MODE: + pDM_Odm->OPMode = (u1Byte)Value; + break; + + case ODM_CMNINFO_WM_MODE: + pDM_Odm->WirelessMode = (u1Byte)Value; + break; + + case ODM_CMNINFO_BAND: + pDM_Odm->BandType = (u1Byte)Value; + break; + + case ODM_CMNINFO_SEC_CHNL_OFFSET: + pDM_Odm->SecChOffset = (u1Byte)Value; + break; + + case ODM_CMNINFO_SEC_MODE: + pDM_Odm->Security = (u1Byte)Value; + break; + + case ODM_CMNINFO_BW: + pDM_Odm->BandWidth = (u1Byte)Value; + break; + + case ODM_CMNINFO_CHNL: + pDM_Odm->Channel = (u1Byte)Value; + break; +*/ + default: + //do nothing + break; + } + + +} + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_InitAllWorkItems(IN PDM_ODM_T pDM_Odm ) +{ +#if USE_WORKITEM + PADAPTER pAdapter = pDM_Odm->Adapter; + + ODM_InitializeWorkItem( pDM_Odm, + &pDM_Odm->DM_SWAT_Table.SwAntennaSwitchWorkitem_8723B, + (RT_WORKITEM_CALL_BACK)ODM_SW_AntDiv_WorkitemCallback, + (PVOID)pAdapter, + "AntennaSwitchWorkitem"); + + ODM_InitializeWorkItem( pDM_Odm, + &pDM_Odm->DM_SWAT_Table.SwAntennaSwitchWorkitem, + (RT_WORKITEM_CALL_BACK)odm_SwAntDivChkAntSwitchWorkitemCallback, + (PVOID)pAdapter, + "AntennaSwitchWorkitem"); + + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->PathDivSwitchWorkitem), + (RT_WORKITEM_CALL_BACK)odm_PathDivChkAntSwitchWorkitemCallback, + (PVOID)pAdapter, + "SWAS_WorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->CCKPathDiversityWorkitem), + (RT_WORKITEM_CALL_BACK)odm_CCKTXPathDiversityWorkItemCallback, + (PVOID)pAdapter, + "CCKTXPathDiversityWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->MPT_DIGWorkitem), + (RT_WORKITEM_CALL_BACK)odm_MPT_DIGWorkItemCallback, + (PVOID)pAdapter, + "MPT_DIGWorkitem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->RaRptWorkitem), + (RT_WORKITEM_CALL_BACK)ODM_UpdateInitRateWorkItemCallback, + (PVOID)pAdapter, + "RaRptWorkitem"); + +#if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) +#if (RTL8188E_SUPPORT == 1) + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->FastAntTrainingWorkitem), + (RT_WORKITEM_CALL_BACK)odm_FastAntTrainingWorkItemCallback, + (PVOID)pAdapter, + "FastAntTrainingWorkitem"); +#endif +#endif + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->DM_RXHP_Table.PSDTimeWorkitem), + (RT_WORKITEM_CALL_BACK)odm_PSD_RXHPWorkitemCallback, + (PVOID)pAdapter, + "PSDRXHP_WorkItem"); +#endif +} + +VOID +ODM_FreeAllWorkItems(IN PDM_ODM_T pDM_Odm ) +{ +#if USE_WORKITEM + ODM_FreeWorkItem( &(pDM_Odm->DM_SWAT_Table.SwAntennaSwitchWorkitem_8723B)); + + ODM_FreeWorkItem( &(pDM_Odm->DM_SWAT_Table.SwAntennaSwitchWorkitem)); + + ODM_FreeWorkItem(&(pDM_Odm->PathDivSwitchWorkitem)); + + ODM_FreeWorkItem(&(pDM_Odm->CCKPathDiversityWorkitem)); + + ODM_FreeWorkItem(&(pDM_Odm->FastAntTrainingWorkitem)); + + ODM_FreeWorkItem(&(pDM_Odm->MPT_DIGWorkitem)); + + ODM_FreeWorkItem(&(pDM_Odm->RaRptWorkitem)); + + ODM_FreeWorkItem((&pDM_Odm->DM_RXHP_Table.PSDTimeWorkitem)); +#endif + +} +#endif + +/* +VOID +odm_FindMinimumRSSI( + IN PDM_ODM_T pDM_Odm + ) +{ + u4Byte i; + u1Byte RSSI_Min = 0xFF; + + for(i=0; ipODM_StaInfo[i] != NULL) + if(IS_STA_VALID(pDM_Odm->pODM_StaInfo[i]) ) + { + if(pDM_Odm->pODM_StaInfo[i]->RSSI_Ave < RSSI_Min) + { + RSSI_Min = pDM_Odm->pODM_StaInfo[i]->RSSI_Ave; + } + } + } + + pDM_Odm->RSSI_Min = RSSI_Min; + +} + +VOID +odm_IsLinked( + IN PDM_ODM_T pDM_Odm + ) +{ + u4Byte i; + BOOLEAN Linked = FALSE; + + for(i=0; ipODM_StaInfo[i]) ) + { + Linked = TRUE; + break; + } + + } + + pDM_Odm->bLinked = Linked; +} +*/ + + +//3============================================================ +//3 DIG +//3============================================================ +/*----------------------------------------------------------------------------- + * Function: odm_DIGInit() + * + * Overview: Set DIG scheme init value. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * + *---------------------------------------------------------------------------*/ + +//Remove DIG by yuchen + +//Remove DIG and FA check by Yu Chen + + +//3============================================================ +//3 BB Power Save +//3============================================================ + +//Remove BB power saving by Yuchen + +//3============================================================ +//3 RATR MASK +//3============================================================ +//3============================================================ +//3 Rate Adaptive +//3============================================================ + +//Remove RAMask by RS_James + +//3============================================================ +//3 Dynamic Tx Power +//3============================================================ + +//Remove BY YuChen + +//Remove Rssimonitorcheck related function to odm_rssimonitorcheck.c + + +VOID +ODM_InitAllTimers( + IN PDM_ODM_T pDM_Odm + ) +{ +#if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) + ODM_AntDivTimers(pDM_Odm,INIT_ANTDIV_TIMMER); +#elif(defined(CONFIG_SW_ANTENNA_DIVERSITY)) + ODM_InitializeTimer(pDM_Odm,&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer, + (RT_TIMER_CALL_BACK)odm_SwAntDivChkAntSwitchCallback, NULL, "SwAntennaSwitchTimer"); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->PSDTimer, + (RT_TIMER_CALL_BACK)dm_PSDMonitorCallback, NULL, "PSDTimer"); + // + //Path Diversity + //Neil Chen--2011--06--16-- / 2012/02/23 MH Revise Arch. + // + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->PathDivSwitchTimer, + (RT_TIMER_CALL_BACK)odm_PathDivChkAntSwitchCallback, NULL, "PathDivTimer"); + + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->CCKPathDiversityTimer, + (RT_TIMER_CALL_BACK)odm_CCKTXPathDiversityCallback, NULL, "CCKPathDiversityTimer"); + + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer, + (RT_TIMER_CALL_BACK)odm_MPT_DIGCallback, NULL, "MPT_DIGTimer"); + + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->DM_RXHP_Table.PSDTimer, + (RT_TIMER_CALL_BACK)odm_PSD_RXHPCallback, NULL, "PSDRXHPTimer"); +#endif +} + +VOID +ODM_CancelAllTimers( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + // + // 2012/01/12 MH Temp BSOD fix. We need to find NIC allocate mem fail reason in + // win7 platform. + // + HAL_ADAPTER_STS_CHK(pDM_Odm) +#endif + +#if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) + ODM_AntDivTimers(pDM_Odm,CANCEL_ANTDIV_TIMMER); +#elif(defined(CONFIG_SW_ANTENNA_DIVERSITY)) + ODM_CancelTimer(pDM_Odm,&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + ODM_CancelTimer(pDM_Odm, &pDM_Odm->PSDTimer); + // + //Path Diversity + //Neil Chen--2011--06--16-- / 2012/02/23 MH Revise Arch. + // + ODM_CancelTimer(pDM_Odm, &pDM_Odm->PathDivSwitchTimer); + + ODM_CancelTimer(pDM_Odm, &pDM_Odm->CCKPathDiversityTimer); + + ODM_CancelTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer); + + ODM_CancelTimer(pDM_Odm, &pDM_Odm->DM_RXHP_Table.PSDTimer); +#endif +} + + +VOID +ODM_ReleaseAllTimers( + IN PDM_ODM_T pDM_Odm + ) +{ +#if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) + ODM_AntDivTimers(pDM_Odm,RELEASE_ANTDIV_TIMMER); +#elif(defined(CONFIG_SW_ANTENNA_DIVERSITY)) + ODM_ReleaseTimer(pDM_Odm,&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->PSDTimer); + // + //Path Diversity + //Neil Chen--2011--06--16-- / 2012/02/23 MH Revise Arch. + // + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->PathDivSwitchTimer); + + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->CCKPathDiversityTimer); + + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer); + + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->DM_RXHP_Table.PSDTimer); +#endif +} + + +//3============================================================ +//3 Tx Power Tracking +//3============================================================ + +VOID +odm_IQCalibrate( + IN PDM_ODM_T pDM_Odm + ) +{ + PADAPTER Adapter = pDM_Odm->Adapter; + +#if( DM_ODM_SUPPORT_TYPE == ODM_WIN) + if(*pDM_Odm->pIsFcsModeEnable) + return; +#endif + + if(!IS_HARDWARE_TYPE_JAGUAR(Adapter)) + return; + else if(IS_HARDWARE_TYPE_8812AU(Adapter)) + return; +#if (RTL8821A_SUPPORT == 1) + if(pDM_Odm->bLinked) + { + if((*pDM_Odm->pChannel != pDM_Odm->preChannel) && (!*pDM_Odm->pbScanInProcess)) + { + pDM_Odm->preChannel = *pDM_Odm->pChannel; + pDM_Odm->LinkedInterval = 0; + } + + if(pDM_Odm->LinkedInterval < 3) + pDM_Odm->LinkedInterval++; + + if(pDM_Odm->LinkedInterval == 2) + { + // Mark out IQK flow to prevent tx stuck. by Maddest 20130306 + // Open it verified by James 20130715 + PHY_IQCalibrate_8821A(pDM_Odm, FALSE); + } + } + else + pDM_Odm->LinkedInterval = 0; +#endif +} + + + +//antenna mapping info +// 1: right-side antenna +// 2/0: left-side antenna +//PDM_SWAT_Table->CCK_Ant1_Cnt /OFDM_Ant1_Cnt: for right-side antenna: Ant:1 RxDefaultAnt1 +//PDM_SWAT_Table->CCK_Ant2_Cnt /OFDM_Ant2_Cnt: for left-side antenna: Ant:0 RxDefaultAnt2 +// We select left antenna as default antenna in initial process, modify it as needed +// + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +// Only for 8723A SW ANT DIV INIT--2012--07--17 +VOID +odm_SwAntDivInit_NIC_8723A( + IN PDM_ODM_T pDM_Odm) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + PADAPTER Adapter = pDM_Odm->Adapter; + + u1Byte btAntNum=BT_GetPgAntNum(Adapter); + + if(IS_HARDWARE_TYPE_8723A(Adapter)) + { + pDM_SWAT_Table->ANTA_ON =TRUE; + + // Set default antenna B status by PG + if(btAntNum == 2) + pDM_SWAT_Table->ANTB_ON = TRUE; + else if(btAntNum == 1) + pDM_SWAT_Table->ANTB_ON = FALSE; + else + pDM_SWAT_Table->ANTB_ON = TRUE; + } + +} + +#endif //end #ifMP + + + +//3============================================================ +//3 SW Antenna Diversity +//3============================================================ + +VOID +odm_AntennaDiversityInit( + IN PDM_ODM_T pDM_Odm +) +{ + if(pDM_Odm->mp_mode == TRUE) + return; + + if(pDM_Odm->SupportICType & (ODM_OLD_IC_ANTDIV_SUPPORT)) + { + #if (RTL8192C_SUPPORT==1) + ODM_OldIC_AntDiv_Init(pDM_Odm); + #endif + } + else + { + #if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) + ODM_AntDiv_Config(pDM_Odm); + ODM_AntDivInit(pDM_Odm); + #endif + } +} + +VOID +odm_AntennaDiversity( + IN PDM_ODM_T pDM_Odm +) +{ + if(pDM_Odm->mp_mode == TRUE) + return; + + if(pDM_Odm->SupportICType & (ODM_OLD_IC_ANTDIV_SUPPORT)) + { + #if (RTL8192C_SUPPORT==1) + ODM_OldIC_AntDiv(pDM_Odm); + #endif + } + else + { + #if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) + ODM_AntDiv(pDM_Odm); + #endif + } +} + + +void +odm_SwAntDetectInit( + IN PDM_ODM_T pDM_Odm + ) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; +#if (RTL8723B_SUPPORT == 1) + pDM_SWAT_Table->SWAS_NoLink_BK_Reg92c = ODM_Read4Byte(pDM_Odm, rDPDT_control); +#endif + pDM_SWAT_Table->PreAntenna = MAIN_ANT; + pDM_SWAT_Table->CurAntenna = MAIN_ANT; + pDM_SWAT_Table->SWAS_NoLink_State = 0; +} + + +//============================================================ +//EDCA Turbo +//============================================================ + +//Remove Edca by Yuchen + + +#if( DM_ODM_SUPPORT_TYPE == ODM_WIN) +// +// 2011/07/26 MH Add an API for testing IQK fail case. +// +BOOLEAN +ODM_CheckPowerStatus( + IN PADAPTER Adapter) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + RT_RF_POWER_STATE rtState; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + + // 2011/07/27 MH We are not testing ready~~!! We may fail to get correct value when init sequence. + if (pMgntInfo->init_adpt_in_progress == TRUE) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ODM_CheckPowerStatus Return TRUE, due to initadapter")); + return TRUE; + } + + // + // 2011/07/19 MH We can not execute tx pwoer tracking/ LLC calibrate or IQK. + // + Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); + if(Adapter->bDriverStopped || Adapter->bDriverIsGoingToPnpSetPowerSleep || rtState == eRfOff) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ODM_CheckPowerStatus Return FALSE, due to %d/%d/%d\n", + Adapter->bDriverStopped, Adapter->bDriverIsGoingToPnpSetPowerSleep, rtState)); + return FALSE; + } + return TRUE; +} +#endif + +// need to ODM CE Platform +//move to here for ANT detection mechanism using + +#if ((DM_ODM_SUPPORT_TYPE == ODM_WIN)||(DM_ODM_SUPPORT_TYPE == ODM_CE)) +u4Byte +GetPSDData( + IN PDM_ODM_T pDM_Odm, + unsigned int point, + u1Byte initial_gain_psd) +{ + //unsigned int val, rfval; + //int psd_report; + u4Byte psd_report; + + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //Debug Message + //val = PHY_QueryBBReg(Adapter,0x908, bMaskDWord); + //DbgPrint("Reg908 = 0x%x\n",val); + //val = PHY_QueryBBReg(Adapter,0xDF4, bMaskDWord); + //rfval = PHY_QueryRFReg(Adapter, ODM_RF_PATH_A, 0x00, bRFRegOffsetMask); + //DbgPrint("RegDF4 = 0x%x, RFReg00 = 0x%x\n",val, rfval); + //DbgPrint("PHYTXON = %x, OFDMCCA_PP = %x, CCKCCA_PP = %x, RFReg00 = %x\n", + //(val&BIT25)>>25, (val&BIT14)>>14, (val&BIT15)>>15, rfval); + + //Set DCO frequency index, offset=(40MHz/SamplePts)*point + ODM_SetBBReg(pDM_Odm, 0x808, 0x3FF, point); + + //Start PSD calculation, Reg808[22]=0->1 + ODM_SetBBReg(pDM_Odm, 0x808, BIT22, 1); + //Need to wait for HW PSD report + ODM_StallExecution(1000); + ODM_SetBBReg(pDM_Odm, 0x808, BIT22, 0); + //Read PSD report, Reg8B4[15:0] + psd_report = ODM_GetBBReg(pDM_Odm,0x8B4, bMaskDWord) & 0x0000FFFF; + +#if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE) && ( (RT_PLATFORM == PLATFORM_LINUX) || (RT_PLATFORM == PLATFORM_MACOSX)) + psd_report = (u4Byte) (ConvertTo_dB(psd_report))+(u4Byte)(initial_gain_psd-0x1c); +#else + psd_report = (int) (20*log10((double)psd_report))+(int)(initial_gain_psd-0x1c); +#endif + + return psd_report; + +} + +u4Byte +ConvertTo_dB( + u4Byte Value) +{ + u1Byte i; + u1Byte j; + u4Byte dB; + + Value = Value & 0xFFFF; + + for (i=0;i<8;i++) + { + if (Value <= dB_Invert_Table[i][11]) + { + break; + } + } + + if (i >= 8) + { + return (96); // maximum 96 dB + } + + for (j=0;j<12;j++) + { + if (Value <= dB_Invert_Table[i][j]) + { + break; + } + } + + dB = i*12 + j + 1; + + return (dB); +} + +#endif + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN| ODM_CE)) + +VOID +odm_PHY_SaveAFERegisters( + IN PDM_ODM_T pDM_Odm, + IN pu4Byte AFEReg, + IN pu4Byte AFEBackup, + IN u4Byte RegisterNum + ) +{ + u4Byte i; + + //RT_DISP(FINIT, INIT_IQK, ("Save ADDA parameters.\n")); + for( i = 0 ; i < RegisterNum ; i++){ + AFEBackup[i] = ODM_GetBBReg(pDM_Odm, AFEReg[i], bMaskDWord); + } +} + +VOID +odm_PHY_ReloadAFERegisters( + IN PDM_ODM_T pDM_Odm, + IN pu4Byte AFEReg, + IN pu4Byte AFEBackup, + IN u4Byte RegiesterNum + ) +{ + u4Byte i; + + //RT_DISP(FINIT, INIT_IQK, ("Reload ADDA power saving parameters !\n")); + for(i = 0 ; i < RegiesterNum; i++) + { + + ODM_SetBBReg(pDM_Odm, AFEReg[i], bMaskDWord, AFEBackup[i]); + } +} + +// +// Description: +// Set Single/Dual Antenna default setting for products that do not do detection in advance. +// +// Added by Joseph, 2012.03.22 +// +VOID +ODM_SingleDualAntennaDefaultSetting( + IN PDM_ODM_T pDM_Odm + ) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + PADAPTER pAdapter = pDM_Odm->Adapter; + u1Byte btAntNum = 2; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + btAntNum=BT_GetPgAntNum(pAdapter); +#elif (DM_ODM_SUPPORT_TYPE & (ODM_CE)) +#ifdef CONFIG_BT_COEXIST + btAntNum = hal_btcoex_GetPgAntNum(pAdapter); +#endif +#endif + + // Set default antenna A and B status + if(btAntNum == 2) + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=TRUE; + //RT_TRACE(COMP_ANTENNA, DBG_LOUD, ("Dual antenna\n")); + } +#ifdef CONFIG_BT_COEXIST + else if(btAntNum == 1) + {// Set antenna A as default + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=FALSE; + //RT_TRACE(COMP_ANTENNA, DBG_LOUD, ("Single antenna\n")); + } + else + { + //RT_ASSERT(FALSE, ("Incorrect antenna number!!\n")); + } +#endif +} + + + +//2 8723A ANT DETECT +// +// Description: +// Implement IQK single tone for RF DPK loopback and BB PSD scanning. +// This function is cooperated with BB team Neil. +// +// Added by Roger, 2011.12.15 +// +BOOLEAN +ODM_SingleDualAntennaDetection( + IN PDM_ODM_T pDM_Odm, + IN u1Byte mode + ) +{ + PADAPTER pAdapter = pDM_Odm->Adapter; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + u4Byte CurrentChannel,RfLoopReg; + u1Byte n; + u4Byte Reg88c, Regc08, Reg874, Regc50, Reg948=0, Regb2c=0, Reg92c=0, AFE_rRx_Wait_CCA=0; + u1Byte initial_gain = 0x5a; + u4Byte PSD_report_tmp; + u4Byte AntA_report = 0x0, AntB_report = 0x0,AntO_report=0x0; + BOOLEAN bResult = TRUE; + u4Byte AFE_Backup[16]; + u4Byte AFE_REG_8723A[16] = { + rRx_Wait_CCA, rTx_CCK_RFON, + rTx_CCK_BBON, rTx_OFDM_RFON, + rTx_OFDM_BBON, rTx_To_Rx, + rTx_To_Tx, rRx_CCK, + rRx_OFDM, rRx_Wait_RIFS, + rRx_TO_Rx, rStandby, + rSleep, rPMPD_ANAEN, + rFPGA0_XCD_SwitchControl, rBlue_Tooth}; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection()============> \n")); + + + if(!(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C|ODM_RTL8723B))) + return bResult; + + // Retrieve antenna detection registry info, added by Roger, 2012.11.27. + if(!IS_ANT_DETECT_SUPPORT_SINGLE_TONE(pAdapter)) + return bResult; + + if(pDM_Odm->SupportICType == ODM_RTL8192C) + { + //Which path in ADC/DAC is turnned on for PSD: both I/Q + ODM_SetBBReg(pDM_Odm, 0x808, BIT10|BIT11, 0x3); + //Ageraged number: 8 + ODM_SetBBReg(pDM_Odm, 0x808, BIT12|BIT13, 0x1); + //pts = 128; + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x0); + } + + //1 Backup Current RF/BB Settings + + CurrentChannel = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask); + RfLoopReg = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x00, bRFRegOffsetMask); + if(!(pDM_Odm->SupportICType == ODM_RTL8723B)) + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); // change to Antenna A +#if (RTL8723B_SUPPORT == 1) + else + { + Reg92c = ODM_GetBBReg(pDM_Odm, 0x92c, bMaskDWord); + Reg948 = ODM_GetBBReg(pDM_Odm, rS0S1_PathSwitch, bMaskDWord); + Regb2c = ODM_GetBBReg(pDM_Odm, AGC_table_select, bMaskDWord); + ODM_SetBBReg(pDM_Odm, rDPDT_control, 0x3, 0x1); + ODM_SetBBReg(pDM_Odm, rfe_ctrl_anta_src, 0xff, 0x77); + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, 0x3ff, 0x000); + ODM_SetBBReg(pDM_Odm, AGC_table_select, BIT31, 0x0); + } +#endif + ODM_StallExecution(10); + + //Store A Path Register 88c, c08, 874, c50 + Reg88c = ODM_GetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord); + Regc08 = ODM_GetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord); + Reg874 = ODM_GetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord); + Regc50 = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord); + + // Store AFE Registers + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + AFE_rRx_Wait_CCA = ODM_GetBBReg(pDM_Odm, rRx_Wait_CCA,bMaskDWord); + + //Set PSD 128 pts + ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT14|BIT15, 0x0); //128 pts + + // To SET CH1 to do + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x7401); //Channel 1 + + // AFE all on step + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + { + ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_CCK_RFON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_CCK_BBON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_OFDM_RFON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_OFDM_BBON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_To_Rx, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_To_Tx, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_CCK, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_OFDM, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_Wait_RIFS, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_TO_Rx, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rStandby, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rSleep, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rPMPD_ANAEN, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_SwitchControl, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rBlue_Tooth, bMaskDWord, 0x6FDB25A4); + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x01c00016); + } + + // 3 wire Disable + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, 0xCCF000C0); + + //BB IQK Setting + ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800E4); + ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22208000); + + //IQK setting tone@ 4.34Mhz + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008C1C); + ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); + + //Page B init + ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00080000); + ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x0f600000); + ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82150008); + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28150008); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x001028d0); + + //RF loop Setting + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x0, 0xFFFFF, 0x50008); + + //IQK Single tone start + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + ODM_StallExecution(10000); + + // PSD report of antenna A + PSD_report_tmp=0x0; + for (n=0;n<2;n++) + { + PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); + if(PSD_report_tmp >AntA_report) + AntA_report=PSD_report_tmp; + } + + // change to Antenna B + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_B); +#if (RTL8723B_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + ODM_SetBBReg(pDM_Odm, rDPDT_control, 0x3, 0x2); +#endif + + ODM_StallExecution(10); + + // PSD report of antenna B + PSD_report_tmp=0x0; + for (n=0;n<2;n++) + { + PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); + if(PSD_report_tmp > AntB_report) + AntB_report=PSD_report_tmp; + } + + // change to open case + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, 0); // change to Antenna A +#if (RTL8723B_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + ODM_SetBBReg(pDM_Odm, rDPDT_control, 0x3, 0x0); +#endif + + ODM_StallExecution(10); + + // PSD report of open case + PSD_report_tmp=0x0; + for (n=0;n<2;n++) + { + PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); + if(PSD_report_tmp > AntO_report) + AntO_report=PSD_report_tmp; + } + + //Close IQK Single Tone function + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + + //1 Return to antanna A + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); // change to Antenna A +#if (RTL8723B_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + // external DPDT + ODM_SetBBReg(pDM_Odm, rDPDT_control, bMaskDWord, Reg92c); + + //internal S0/S1 + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, bMaskDWord, Reg948); + ODM_SetBBReg(pDM_Odm, AGC_table_select, bMaskDWord, Regb2c); + } +#endif + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, Reg88c); + ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, Regc08); + ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, Reg874); + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord, Regc50); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,CurrentChannel); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x00, bRFRegOffsetMask,RfLoopReg); + + //Reload AFE Registers + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, AFE_rRx_Wait_CCA); + + if(pDM_Odm->SupportICType == ODM_RTL8723A) + { + //2 Test Ant B based on Ant A is ON + if(mode==ANTTESTB) + { + if(AntA_report >= 100) + { + if(AntB_report > (AntA_report+1)) + { + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n")); + } + else + { + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Dual Antenna is A and B\n")); + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + pDM_SWAT_Table->ANTB_ON=FALSE; // Set Antenna B off as default + bResult = FALSE; + } + } + //2 Test Ant A and B based on DPDT Open + else if(mode==ANTTESTALL) + { + if((AntO_report >=100) && (AntO_report <=118)) + { + if(AntA_report > (AntO_report+1)) + { + pDM_SWAT_Table->ANTA_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant A is OFF\n")); + } + else + { + pDM_SWAT_Table->ANTA_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant A is ON\n")); + } + + if(AntB_report > (AntO_report+2)) + { + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant B is OFF\n")); + } + else + { + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant B is ON\n")); + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_A[%d]= %d \n", 2416, AntA_report)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_B[%d]= %d \n", 2416, AntB_report)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_O[%d]= %d \n", 2416, AntO_report)); + + pDM_Odm->AntDetectedInfo.bAntDetected= TRUE; + pDM_Odm->AntDetectedInfo.dBForAntA = AntA_report; + pDM_Odm->AntDetectedInfo.dBForAntB = AntB_report; + pDM_Odm->AntDetectedInfo.dBForAntO = AntO_report; + + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("return FALSE!!\n")); + bResult = FALSE; + } + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8192C) + { + if(AntA_report >= 100) + { + if(AntB_report > (AntA_report+2)) + { + pDM_SWAT_Table->ANTA_ON=FALSE; + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna B\n")); + } + else if(AntA_report > (AntB_report+2)) + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n")); + } + else + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=TRUE; + RT_TRACE(COMP_ANTENNA, DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Dual Antenna \n")); + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + pDM_SWAT_Table->ANTA_ON=TRUE; // Set Antenna A on as default + pDM_SWAT_Table->ANTB_ON=FALSE; // Set Antenna B off as default + bResult = FALSE; + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_A[%d]= %d \n", 2416, AntA_report)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_B[%d]= %d \n", 2416, AntB_report)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_O[%d]= %d \n", 2416, AntO_report)); + + //2 Test Ant B based on Ant A is ON + if(mode==ANTTESTB) + { + if(AntA_report >=100 && AntA_report <= 116) + { + if(AntB_report >= (AntA_report+4) && AntB_report > 116) + { + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n")); + } + else if(AntB_report >=100 && AntB_report <= 116) + { + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Dual Antenna is A and B\n")); + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + pDM_SWAT_Table->ANTB_ON=FALSE; // Set Antenna B off as default + bResult = FALSE; + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + pDM_SWAT_Table->ANTB_ON=FALSE; // Set Antenna B off as default + bResult = FALSE; + } + } + //2 Test Ant A and B based on DPDT Open + else if(mode==ANTTESTALL) + { + if((AntA_report >= 100) && (AntB_report >= 100) && (AntA_report <= 120) && (AntB_report <= 120)) + { + if((AntA_report - AntB_report < 2) || (AntB_report - AntA_report < 2)) + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ODM_SingleDualAntennaDetection(): Dual Antenna\n")); + } + else if(((AntA_report - AntB_report >= 2) && (AntA_report - AntB_report <= 4)) || + ((AntB_report - AntA_report >= 2) && (AntB_report - AntA_report <= 4))) + { + pDM_SWAT_Table->ANTA_ON=FALSE; + pDM_SWAT_Table->ANTB_ON=FALSE; + bResult = FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + } + else + { + pDM_SWAT_Table->ANTA_ON = TRUE; + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ODM_SingleDualAntennaDetection(): Single Antenna A\n")); + } + + pDM_Odm->AntDetectedInfo.bAntDetected= TRUE; + pDM_Odm->AntDetectedInfo.dBForAntA = AntA_report; + pDM_Odm->AntDetectedInfo.dBForAntB = AntB_report; + pDM_Odm->AntDetectedInfo.dBForAntO = AntO_report; + + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("return FALSE!!\n")); + bResult = FALSE; + } + } + } + + return bResult; + +} + + +#endif // end odm_CE + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN| ODM_CE)) + +VOID +odm_Set_RA_DM_ARFB_by_Noisy( + IN PDM_ODM_T pDM_Odm +) +{ + //DbgPrint("DM_ARFB ====> \n"); + if (pDM_Odm->bNoisyState){ + ODM_Write4Byte(pDM_Odm,0x430,0x00000000); + ODM_Write4Byte(pDM_Odm,0x434,0x05040200); + //DbgPrint("DM_ARFB ====> Noisy State\n"); + } + else{ + ODM_Write4Byte(pDM_Odm,0x430,0x02010000); + ODM_Write4Byte(pDM_Odm,0x434,0x07050403); + //DbgPrint("DM_ARFB ====> Clean State\n"); + } + +} + +VOID +ODM_UpdateNoisyState( + IN PDM_ODM_T pDM_Odm, + IN BOOLEAN bNoisyStateFromC2H + ) +{ + //DbgPrint("Get C2H Command! NoisyState=0x%x\n ", bNoisyStateFromC2H); + if(pDM_Odm->SupportICType == ODM_RTL8821 || pDM_Odm->SupportICType == ODM_RTL8812 || + pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8188E) + { + pDM_Odm->bNoisyState = bNoisyStateFromC2H; + } + odm_Set_RA_DM_ARFB_by_Noisy(pDM_Odm); +}; + +u4Byte +Set_RA_DM_Ratrbitmap_by_Noisy( + IN PDM_ODM_T pDM_Odm, + IN WIRELESS_MODE WirelessMode, + IN u4Byte ratr_bitmap, + IN u1Byte rssi_level +) +{ + u4Byte ret_bitmap = ratr_bitmap; + switch (WirelessMode) + { + case WIRELESS_MODE_AC_24G : + case WIRELESS_MODE_AC_5G : + case WIRELESS_MODE_AC_ONLY: + if (pDM_Odm->bNoisyState){ // in Noisy State + if (rssi_level==1) + ret_bitmap&=0xfe3f0e08; + else if (rssi_level==2) + ret_bitmap&=0xff3f8f8c; + else if (rssi_level==3) + ret_bitmap&=0xffffffcc ; + else + ret_bitmap&=0xffffffff ; + } + else{ // in SNR State + if (rssi_level==1){ + ret_bitmap&=0xfc3e0c08; + } + else if (rssi_level==2){ + ret_bitmap&=0xfe3f0e08; + } + else if (rssi_level==3){ + ret_bitmap&=0xffbfefcc; + } + else{ + ret_bitmap&=0x0fffffff; + } + } + break; + case WIRELESS_MODE_B: + case WIRELESS_MODE_A: + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + if (pDM_Odm->bNoisyState){ + if (rssi_level==1) + ret_bitmap&=0x0f0e0c08; + else if (rssi_level==2) + ret_bitmap&=0x0f8f0e0c; + else if (rssi_level==3) + ret_bitmap&=0x0fefefcc ; + else + ret_bitmap&=0xffffffff ; + } + else{ + if (rssi_level==1){ + ret_bitmap&=0x0f8f0e08; + } + else if (rssi_level==2){ + ret_bitmap&=0x0fcf8f8c; + } + else if (rssi_level==3){ + ret_bitmap&=0x0fffffcc; + } + else{ + ret_bitmap&=0x0fffffff; + } + } + break; + default: + break; + } + //DbgPrint("DM_RAMask ====> rssi_LV = %d, BITMAP = %x \n", rssi_level, ret_bitmap); + return ret_bitmap; + +} + + + +VOID +ODM_UpdateInitRate( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Rate + ) +{ + u1Byte p = 0; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Get C2H Command! Rate=0x%x\n", Rate)); + + if(pDM_Odm->SupportICType == ODM_RTL8821 || pDM_Odm->SupportICType == ODM_RTL8812 || + pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8188E) + { + pDM_Odm->TxRate = Rate; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if DEV_BUS_TYPE==RT_PCI_INTERFACE + #if USE_WORKITEM + PlatformScheduleWorkItem(&pDM_Odm->RaRptWorkitem); + #else + if(pDM_Odm->SupportICType == ODM_RTL8821) + { + ODM_TxPwrTrackSetPwr8821A(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); + } + else if(pDM_Odm->SupportICType == ODM_RTL8812) + { + for (p = ODM_RF_PATH_A; p < MAX_PATH_NUM_8812A; p++) + { + ODM_TxPwrTrackSetPwr8812A(pDM_Odm, MIX_MODE, p, 0); + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_TxPwrTrackSetPwr_8723B(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); + } + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + for (p = ODM_RF_PATH_A; p < MAX_PATH_NUM_8192E; p++) + { + ODM_TxPwrTrackSetPwr92E(pDM_Odm, MIX_MODE, p, 0); + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + ODM_TxPwrTrackSetPwr88E(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); + } + #endif + #else + PlatformScheduleWorkItem(&pDM_Odm->RaRptWorkitem); + #endif +#endif + } + else + return; +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_UpdateInitRateWorkItemCallback( + IN PVOID pContext + ) +{ + PADAPTER Adapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + u1Byte p = 0; + + if(pDM_Odm->SupportICType == ODM_RTL8821) + { + ODM_TxPwrTrackSetPwr8821A(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); + } + else if(pDM_Odm->SupportICType == ODM_RTL8812) + { + for (p = ODM_RF_PATH_A; p < MAX_PATH_NUM_8812A; p++) //DOn't know how to include &c + { + ODM_TxPwrTrackSetPwr8812A(pDM_Odm, MIX_MODE, p, 0); + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_TxPwrTrackSetPwr_8723B(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); + } + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + for (p = ODM_RF_PATH_A; p < MAX_PATH_NUM_8192E; p++) //DOn't know how to include &c + { + ODM_TxPwrTrackSetPwr92E(pDM_Odm, MIX_MODE, p, 0); + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + ODM_TxPwrTrackSetPwr88E(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); + } +} +#endif +#endif + +// +// ODM multi-port consideration, added by Roger, 2013.10.01. +// +VOID +ODM_AsocEntry_Init( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER pLoopAdapter = GetDefaultAdapter(pDM_Odm->Adapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pLoopAdapter); + PDM_ODM_T pDM_OutSrc = &pHalData->DM_OutSrc; + u1Byte TotalAssocEntryNum = 0; + u1Byte index = 0; + + + ODM_CmnInfoPtrArrayHook(pDM_OutSrc, ODM_CMNINFO_STA_STATUS, 0, &pLoopAdapter->MgntInfo.DefaultPort[0]); + pLoopAdapter->MgntInfo.DefaultPort[0].MultiPortStationIdx = TotalAssocEntryNum; + + pLoopAdapter = GetNextExtAdapter(pLoopAdapter); + TotalAssocEntryNum +=1; + + while(pLoopAdapter) + { + for (index = 0; index MgntInfo.AsocEntry[index]); + pLoopAdapter->MgntInfo.AsocEntry[index].MultiPortStationIdx = TotalAssocEntryNum+index; + } + + TotalAssocEntryNum+= index; + if(IS_HARDWARE_TYPE_8188E((pDM_Odm->Adapter))) + pLoopAdapter->RASupport = TRUE; + pLoopAdapter = GetNextExtAdapter(pLoopAdapter); + } +#endif +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +/* Justin: According to the current RRSI to adjust Response Frame TX power, 2012/11/05 */ +void odm_dtc(PDM_ODM_T pDM_Odm) +{ +#ifdef CONFIG_DM_RESP_TXAGC + #define DTC_BASE 35 /* RSSI higher than this value, start to decade TX power */ + #define DTC_DWN_BASE (DTC_BASE-5) /* RSSI lower than this value, start to increase TX power */ + + /* RSSI vs TX power step mapping: decade TX power */ + static const u8 dtc_table_down[]={ + DTC_BASE, + (DTC_BASE+5), + (DTC_BASE+10), + (DTC_BASE+15), + (DTC_BASE+20), + (DTC_BASE+25) + }; + + /* RSSI vs TX power step mapping: increase TX power */ + static const u8 dtc_table_up[]={ + DTC_DWN_BASE, + (DTC_DWN_BASE-5), + (DTC_DWN_BASE-10), + (DTC_DWN_BASE-15), + (DTC_DWN_BASE-15), + (DTC_DWN_BASE-20), + (DTC_DWN_BASE-20), + (DTC_DWN_BASE-25), + (DTC_DWN_BASE-25), + (DTC_DWN_BASE-30), + (DTC_DWN_BASE-35) + }; + + u8 i; + u8 dtc_steps=0; + u8 sign; + u8 resp_txagc=0; + + #if 0 + /* As DIG is disabled, DTC is also disable */ + if(!(pDM_Odm->SupportAbility & ODM_XXXXXX)) + return; + #endif + + if (DTC_BASE < pDM_Odm->RSSI_Min) { + /* need to decade the CTS TX power */ + sign = 1; + for (i=0;i= pDM_Odm->RSSI_Min) || (dtc_steps >= 6)) + break; + else + dtc_steps++; + } + } +#if 0 + else if (DTC_DWN_BASE > pDM_Odm->RSSI_Min) + { + /* needs to increase the CTS TX power */ + sign = 0; + dtc_steps = 1; + for (i=0;iRSSI_Min) || (dtc_steps>=10)) + break; + else + dtc_steps++; + } + } +#endif + else + { + sign = 0; + dtc_steps = 0; + } + + resp_txagc = dtc_steps | (sign << 4); + resp_txagc = resp_txagc | (resp_txagc << 5); + ODM_Write1Byte(pDM_Odm, 0x06d9, resp_txagc); + + DBG_871X("%s RSSI_Min:%u, set RESP_TXAGC to %s %u\n", + __func__, pDM_Odm->RSSI_Min, sign?"minus":"plus", dtc_steps); +#endif /* CONFIG_RESP_TXAGC_ADJUST */ +} + +#endif /* #if (DM_ODM_SUPPORT_TYPE == ODM_CE) */ + +VOID +odm_UpdatePowerTrainingState( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm , PHYDM_FALSEALMCNT); + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + u4Byte score = 0; + + if(!(pDM_Odm->SupportAbility & ODM_BB_PWR_TRAIN)) + return; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState()============>\n")); + pDM_Odm->bChangeState = FALSE; + + // Debug command + if(pDM_Odm->ForcePowerTrainingState) + { + if(pDM_Odm->ForcePowerTrainingState == 1 && !pDM_Odm->bDisablePowerTraining) + { + pDM_Odm->bChangeState = TRUE; + pDM_Odm->bDisablePowerTraining = TRUE; + } + else if(pDM_Odm->ForcePowerTrainingState == 2 && pDM_Odm->bDisablePowerTraining) + { + pDM_Odm->bChangeState = TRUE; + pDM_Odm->bDisablePowerTraining = FALSE; + } + + pDM_Odm->PT_score = 0; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM = 0; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK = 0; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): ForcePowerTrainingState = %d\n", + pDM_Odm->ForcePowerTrainingState)); + return; + } + + if(!pDM_Odm->bLinked) + return; + + // First connect + if((pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == FALSE)) + { + pDM_Odm->PT_score = 0; + pDM_Odm->bChangeState = TRUE; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM = 0; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK = 0; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): First Connect\n")); + return; + } + + // Compute score + if(pDM_Odm->NHM_cnt_0 >= 215) + score = 2; + else if(pDM_Odm->NHM_cnt_0 >= 190) + score = 1; // unknow state + else + { + u4Byte RX_Pkt_Cnt; + + RX_Pkt_Cnt = (u4Byte)(pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM) + (u4Byte)(pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK); + + if((FalseAlmCnt->Cnt_CCA_all > 31 && RX_Pkt_Cnt > 31) && (FalseAlmCnt->Cnt_CCA_all >= RX_Pkt_Cnt)) + { + if((RX_Pkt_Cnt + (RX_Pkt_Cnt >> 1)) <= FalseAlmCnt->Cnt_CCA_all) + score = 0; + else if((RX_Pkt_Cnt + (RX_Pkt_Cnt >> 2)) <= FalseAlmCnt->Cnt_CCA_all) + score = 1; + else + score = 2; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): RX_Pkt_Cnt = %d, Cnt_CCA_all = %d\n", + RX_Pkt_Cnt, FalseAlmCnt->Cnt_CCA_all)); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): NumQryPhyStatusOFDM = %d, NumQryPhyStatusCCK = %d\n", + (u4Byte)(pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM), (u4Byte)(pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK))); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): NHM_cnt_0 = %d, score = %d\n", + pDM_Odm->NHM_cnt_0, score)); + + // smoothing + pDM_Odm->PT_score = (score << 4) + (pDM_Odm->PT_score>>1) + (pDM_Odm->PT_score>>2); + score = (pDM_Odm->PT_score + 32) >> 6; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): PT_score = %d, score after smoothing = %d\n", + pDM_Odm->PT_score, score)); + + // Mode decision + if(score == 2) + { + if(pDM_Odm->bDisablePowerTraining) + { + pDM_Odm->bChangeState = TRUE; + pDM_Odm->bDisablePowerTraining = FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): Change state\n")); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): Enable Power Training\n")); + } + else if(score == 0) + { + if(!pDM_Odm->bDisablePowerTraining) + { + pDM_Odm->bChangeState = TRUE; + pDM_Odm->bDisablePowerTraining = TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): Change state\n")); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_RA_MASK, ODM_DBG_LOUD,("odm_UpdatePowerTrainingState(): Disable Power Training\n")); + } + + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM = 0; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK = 0; +#endif +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm.h new file mode 100755 index 000000000000..3a50704ce852 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm.h @@ -0,0 +1,2000 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __HALDMOUTSRC_H__ +#define __HALDMOUTSRC_H__ + +//============================================================ +// include files +//============================================================ +#include "phydm_DIG.h" +#include "phydm_EdcaTurboCheck.h" +#include "phydm_PathDiv.h" +#include "phydm_DynamicBBPowerSaving.h" +#include "phydm_RaInfo.h" +#include "phydm_DynamicTxPower.h" +#include "phydm_CfoTracking.h" +#include "phydm_ACS.h" +#include "phydm_PowerTracking.h" +#include "PhyDM_Adaptivity.h" +#include "phydm_NoiseMonitor.h" +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) +#include "phydm_RXHP.h" +#endif + +//============================================================ +// Definition +//============================================================ +// +// 2011/09/22 MH Define all team supprt ability. +// + +// +// 2011/09/22 MH Define for all teams. Please Define the constan in your precomp header. +// +//#define DM_ODM_SUPPORT_AP 0 +//#define DM_ODM_SUPPORT_ADSL 0 +//#define DM_ODM_SUPPORT_CE 0 +//#define DM_ODM_SUPPORT_MP 1 + +// +// 2011/09/28 MH Define ODM SW team support flag. +// + + + +// +// Antenna Switch Relative Definition. +// + +// +// 20100503 Joseph: +// Add new function SwAntDivCheck8192C(). +// This is the main function of Antenna diversity function before link. +// Mainly, it just retains last scan result and scan again. +// After that, it compares the scan result to see which one gets better RSSI. +// It selects antenna with better receiving power and returns better scan result. +// +#define TP_MODE 0 +#define RSSI_MODE 1 +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 +#define NONE 0 + + +//============================================================ +//3 Tx Power Tracking +//3============================================================ + + +//============================================================ +//3 PSD Handler +//3============================================================ + +#define AFH_PSD 1 //0:normal PSD scan, 1: only do 20 pts PSD +#define MODE_40M 0 //0:20M, 1:40M +#define PSD_TH2 3 +#define PSD_CHMIN 20 // Minimum channel number for BT AFH +#define SIR_STEP_SIZE 3 +#define Smooth_Size_1 5 +#define Smooth_TH_1 3 +#define Smooth_Size_2 10 +#define Smooth_TH_2 4 +#define Smooth_Size_3 20 +#define Smooth_TH_3 4 +#define Smooth_Step_Size 5 +#define Adaptive_SIR 1 +#if(RTL8723_FPGA_VERIFICATION == 1) +#define PSD_RESCAN 1 +#else +#define PSD_RESCAN 4 +#endif +#define PSD_SCAN_INTERVAL 700 //ms + + + +//8723A High Power IGI Setting +#define DM_DIG_HIGH_PWR_IGI_LOWER_BOUND 0x22 +#define DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND 0x28 +#define DM_DIG_HIGH_PWR_THRESHOLD 0x3a +#define DM_DIG_LOW_PWR_THRESHOLD 0x14 + +//ANT Test +#define ANTTESTALL 0x00 //Ant A or B will be Testing +#define ANTTESTA 0x01 //Ant A will be Testing +#define ANTTESTB 0x02 //Ant B will be testing + +//for 8723A Ant Definition--2012--06--07 due to different IC may be different ANT define +#define MAIN_ANT 1 //Ant A or Ant Main +#define AUX_ANT 2 //AntB or Ant Aux +#define MAX_ANT 3 // 3 for AP using + + +//Antenna Diversity Type +#define SW_ANTDIV 0 +#define HW_ANTDIV 1 +//============================================================ +// structure and define +//============================================================ + +// +// 2011/09/20 MH Add for AP/ADSLpseudo DM structuer requirement. +// We need to remove to other position??? +// +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) +typedef struct rtl8192cd_priv { + u1Byte temp; + +}rtl8192cd_priv, *prtl8192cd_priv; +#endif + + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +typedef struct _ADAPTER{ + u1Byte temp; + #ifdef AP_BUILD_WORKAROUND + HAL_DATA_TYPE* temp2; + prtl8192cd_priv priv; + #endif +}ADAPTER, *PADAPTER; +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + +typedef struct _WLAN_STA{ + u1Byte temp; +} WLAN_STA, *PRT_WLAN_STA; + +#endif + +//Remove DIG by Yuchen + +//Remoce BB power saving by Yuchn + +//Remove DIG by yuchen + +typedef struct _Dynamic_Primary_CCA{ + u1Byte PriCCA_flag; + u1Byte intf_flag; + u1Byte intf_type; + u1Byte DupRTS_flag; + u1Byte Monitor_flag; + u1Byte CH_offset; + u1Byte MF_state; +}Pri_CCA_T, *pPri_CCA_T; + +//Remove RA_T,*pRA_T by RS_James + +typedef struct _RX_High_Power_ +{ + u1Byte RXHP_flag; + u1Byte PSD_func_trigger; + u1Byte PSD_bitmap_RXHP[80]; + u1Byte Pre_IGI; + u1Byte Cur_IGI; + u1Byte Pre_pw_th; + u1Byte Cur_pw_th; + BOOLEAN First_time_enter; + BOOLEAN RXHP_enable; + u1Byte TP_Mode; + RT_TIMER PSDTimer; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if USE_WORKITEM + RT_WORK_ITEM PSDTimeWorkitem; + #endif +#endif + +}RXHP_T, *pRXHP_T; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE)) +#define ASSOCIATE_ENTRY_NUM 32 // Max size of AsocEntry[]. +#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM + +#elif(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#define ASSOCIATE_ENTRY_NUM NUM_STAT +#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM+1 + +#else +// +// 2012/01/12 MH Revise for compatiable with other SW team. +// 0 is for STA 1-n is for AP clients. +// +#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM+1// Default port only one +#endif + +//#ifdef CONFIG_ANTENNA_DIVERSITY +// This indicates two different the steps. +// In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. +// In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK +// with original RSSI to determine if it is necessary to switch antenna. +#define SWAW_STEP_PEAK 0 +#define SWAW_STEP_DETERMINE 1 + +#define TP_MODE 0 +#define RSSI_MODE 1 +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 +#define TRAFFIC_UltraLOW 2 + +typedef struct _SW_Antenna_Switch_ +{ + u1Byte Double_chk_flag; + u1Byte try_flag; + s4Byte PreRSSI; + u1Byte CurAntenna; + u1Byte PreAntenna; + u1Byte RSSI_Trying; + u1Byte TestMode; + u1Byte bTriggerAntennaSwitch; + u1Byte SelectAntennaMap; + u1Byte RSSI_target; + u1Byte reset_idx; + u2Byte Single_Ant_Counter; + u2Byte Dual_Ant_Counter; + u2Byte Aux_FailDetec_Counter; + u2Byte Retry_Counter; + + // Before link Antenna Switch check + u1Byte SWAS_NoLink_State; + u4Byte SWAS_NoLink_BK_Reg860; + u4Byte SWAS_NoLink_BK_Reg92c; + u4Byte SWAS_NoLink_BK_Reg948; + BOOLEAN ANTA_ON; //To indicate Ant A is or not + BOOLEAN ANTB_ON; //To indicate Ant B is on or not + BOOLEAN Pre_Aux_FailDetec; + BOOLEAN RSSI_AntDect_bResult; + u1Byte Ant5G; + u1Byte Ant2G; + + s4Byte RSSI_sum_A; + s4Byte RSSI_sum_B; + s4Byte RSSI_cnt_A; + s4Byte RSSI_cnt_B; + + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u8Byte TXByteCnt_A; + u8Byte TXByteCnt_B; + u8Byte RXByteCnt_A; + u8Byte RXByteCnt_B; + u1Byte TrafficLoad; + u1Byte Train_time; + u1Byte Train_time_flag; + RT_TIMER SwAntennaSwitchTimer; +#if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + RT_TIMER SwAntennaSwitchTimer_8723B; + u4Byte PktCnt_SWAntDivByCtrlFrame; + BOOLEAN bSWAntDivByCtrlFrame; +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if USE_WORKITEM + RT_WORK_ITEM SwAntennaSwitchWorkitem; +#if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + RT_WORK_ITEM SwAntennaSwitchWorkitem_8723B; + #endif +#endif +#endif +/* CE Platform use +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + _timer SwAntennaSwitchTimer; + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u8Byte TXByteCnt_A; + u8Byte TXByteCnt_B; + u8Byte RXByteCnt_A; + u8Byte RXByteCnt_B; + u1Byte DoubleComfirm; + u1Byte TrafficLoad; + //SW Antenna Switch + + +#endif +*/ +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + //Hybrid Antenna Diversity + u4Byte CCK_Ant1_Cnt[ASSOCIATE_ENTRY_NUM+1]; + u4Byte CCK_Ant2_Cnt[ASSOCIATE_ENTRY_NUM+1]; + u4Byte OFDM_Ant1_Cnt[ASSOCIATE_ENTRY_NUM+1]; + u4Byte OFDM_Ant2_Cnt[ASSOCIATE_ENTRY_NUM+1]; + u4Byte RSSI_Ant1_Sum[ASSOCIATE_ENTRY_NUM+1]; + u4Byte RSSI_Ant2_Sum[ASSOCIATE_ENTRY_NUM+1]; + u1Byte TxAnt[ASSOCIATE_ENTRY_NUM+1]; + u1Byte TargetSTA; + u1Byte antsel; + u1Byte RxIdleAnt; + +#endif + +}SWAT_T, *pSWAT_T; +//#endif + +// Edca Remove by YuChen + +//ODM_RATE_ADAPTIVE Remove by RS_James + + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + + +#ifdef ADSL_AP_BUILD_WORKAROUND +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 //ms +#endif + +// +// Indicate different AP vendor for IOT issue. +// +typedef enum _HT_IOT_PEER +{ + HT_IOT_PEER_UNKNOWN = 0, + HT_IOT_PEER_REALTEK = 1, + HT_IOT_PEER_REALTEK_92SE = 2, + HT_IOT_PEER_BROADCOM = 3, + HT_IOT_PEER_RALINK = 4, + HT_IOT_PEER_ATHEROS = 5, + HT_IOT_PEER_CISCO = 6, + HT_IOT_PEER_MERU = 7, + HT_IOT_PEER_MARVELL = 8, + HT_IOT_PEER_REALTEK_SOFTAP = 9,// peer is RealTek SOFT_AP, by Bohn, 2009.12.17 + HT_IOT_PEER_SELF_SOFTAP = 10, // Self is SoftAP + HT_IOT_PEER_AIRGO = 11, + HT_IOT_PEER_INTEL = 12, + HT_IOT_PEER_RTK_APCLIENT = 13, + HT_IOT_PEER_REALTEK_81XX = 14, + HT_IOT_PEER_REALTEK_WOW = 15, + HT_IOT_PEER_MAX = 16 +}HT_IOT_PEER_E, *PHTIOT_PEER_E; +#endif//#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#define DM_Type_ByFW 0 +#define DM_Type_ByDriver 1 + +// +// Declare for common info +// +#define MAX_PATH_NUM_92CS 2 +#define MAX_PATH_NUM_8188E 1 +#define MAX_PATH_NUM_8192E 2 +#define MAX_PATH_NUM_8723B 1 +#define MAX_PATH_NUM_8812A 2 +#define MAX_PATH_NUM_8821A 1 +#define MAX_PATH_NUM_8814A 4 +#define MAX_PATH_NUM_8822B 2 + + +#define IQK_THRESHOLD 8 +#define DPK_THRESHOLD 4 + +typedef struct _ODM_Phy_Status_Info_ +{ + // + // Be care, if you want to add any element please insert between + // RxPWDBAll & SignalStrength. + // +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + u4Byte RxPWDBAll; +#else + u1Byte RxPWDBAll; +#endif + + u1Byte SignalQuality; // in 0-100 index. + s1Byte RxMIMOSignalQuality[4]; //per-path's EVM + u1Byte RxMIMOEVMdbm[4]; //per-path's EVM dbm + + u1Byte RxMIMOSignalStrength[4];// in 0~100 index + + u2Byte Cfo_short[4]; // per-path's Cfo_short + u2Byte Cfo_tail[4]; // per-path's Cfo_tail + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + s1Byte RxPower; // in dBm Translate from PWdB + s1Byte RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. Keep this raw info to be used for the other procedures. + u1Byte BTRxRSSIPercentage; + u1Byte SignalStrength; // in 0-100 index. + + s1Byte RxPwr[4]; //per-path's pwdb +#endif + u1Byte RxSNR[4]; //per-path's SNR + u1Byte BandWidth; + u1Byte btCoexPwrAdjust; +}ODM_PHY_INFO_T,*PODM_PHY_INFO_T; + + +typedef struct _ODM_Per_Pkt_Info_ +{ + //u1Byte Rate; + u1Byte DataRate; + u1Byte StationID; + BOOLEAN bPacketMatchBSSID; + BOOLEAN bPacketToSelf; + BOOLEAN bPacketBeacon; + BOOLEAN bToSelf; +}ODM_PACKET_INFO_T,*PODM_PACKET_INFO_T; + + +typedef struct _ODM_Phy_Dbg_Info_ +{ + //ODM Write,debug info + s1Byte RxSNRdB[4]; + u4Byte NumQryPhyStatus; + u4Byte NumQryPhyStatusCCK; + u4Byte NumQryPhyStatusOFDM; + u1Byte NumQryBeaconPkt; + //Others + s4Byte RxEVM[4]; + +}ODM_PHY_DBG_INFO_T; + + +typedef struct _ODM_Mac_Status_Info_ +{ + u1Byte test; + +}ODM_MAC_INFO; + + +typedef enum tag_Dynamic_ODM_Support_Ability_Type +{ + // BB Team + ODM_DIG = 0x00000001, + ODM_HIGH_POWER = 0x00000002, + ODM_CCK_CCA_TH = 0x00000004, + ODM_FA_STATISTICS = 0x00000008, + ODM_RAMASK = 0x00000010, + ODM_RSSI_MONITOR = 0x00000020, + ODM_SW_ANTDIV = 0x00000040, + ODM_HW_ANTDIV = 0x00000080, + ODM_BB_PWRSV = 0x00000100, + ODM_2TPATHDIV = 0x00000200, + ODM_1TPATHDIV = 0x00000400, + ODM_PSD2AFH = 0x00000800 +}ODM_Ability_E; + +// +// 2011/20/20 MH For MP driver RT_WLAN_STA = STA_INFO_T +// Please declare below ODM relative info in your STA info structure. +// +#if 1 +typedef struct _ODM_STA_INFO{ + // Driver Write + BOOLEAN bUsed; // record the sta status link or not? + //u1Byte WirelessMode; // + u1Byte IOTPeer; // Enum value. HT_IOT_PEER_E + + // ODM Write + //1 PHY_STATUS_INFO + u1Byte RSSI_Path[4]; // + u1Byte RSSI_Ave; + u1Byte RXEVM[4]; + u1Byte RXSNR[4]; + + // ODM Write + //1 TX_INFO (may changed by IC) + //TX_INFO_T pTxInfo; // Define in IC folder. Move lower layer. +#if 0 + u1Byte ANTSEL_A; //in Jagar: 4bit; others: 2bit + u1Byte ANTSEL_B; //in Jagar: 4bit; others: 2bit + u1Byte ANTSEL_C; //only in Jagar: 4bit + u1Byte ANTSEL_D; //only in Jagar: 4bit + u1Byte TX_ANTL; //not in Jagar: 2bit + u1Byte TX_ANT_HT; //not in Jagar: 2bit + u1Byte TX_ANT_CCK; //not in Jagar: 2bit + u1Byte TXAGC_A; //not in Jagar: 4bit + u1Byte TXAGC_B; //not in Jagar: 4bit + u1Byte TXPWR_OFFSET; //only in Jagar: 3bit + u1Byte TX_ANT; //only in Jagar: 4bit for TX_ANTL/TX_ANTHT/TX_ANT_CCK +#endif + + // + // Please use compile flag to disabe the strcutrue for other IC except 88E. + // Move To lower layer. + // + // ODM Write Wilson will handle this part(said by Luke.Lee) + //TX_RPT_T pTxRpt; // Define in IC folder. Move lower layer. +#if 0 + //1 For 88E RA (don't redefine the naming) + u1Byte rate_id; + u1Byte rate_SGI; + u1Byte rssi_sta_ra; + + u1Byte SGI_enable; + u1Byte Decision_rate; + u1Byte Pre_rate; + u1Byte Active; + + // Driver write Wilson handle. + //1 TX_RPT (don't redefine the naming) + u2Byte RTY[4]; // ??? + u2Byte TOTAL; // ??? + u2Byte DROP; // ??? + // + // Please use compile flag to disabe the strcutrue for other IC except 88E. + // +#endif + +}ODM_STA_INFO_T, *PODM_STA_INFO_T; +#endif + +// +// 2011/10/20 MH Define Common info enum for all team. +// +typedef enum _ODM_Common_Info_Definition +{ +//-------------REMOVED CASE-----------// + //ODM_CMNINFO_CCK_HP, + //ODM_CMNINFO_RFPATH_ENABLE, // Define as ODM write??? + //ODM_CMNINFO_BT_COEXIST, // ODM_BT_COEXIST_E + //ODM_CMNINFO_OP_MODE, // ODM_OPERATION_MODE_E +//-------------REMOVED CASE-----------// + + // + // Fixed value: + // + + //-----------HOOK BEFORE REG INIT-----------// + ODM_CMNINFO_PLATFORM = 0, + ODM_CMNINFO_ABILITY, // ODM_ABILITY_E + ODM_CMNINFO_INTERFACE, // ODM_INTERFACE_E + ODM_CMNINFO_MP_TEST_CHIP, + ODM_CMNINFO_IC_TYPE, // ODM_IC_TYPE_E + ODM_CMNINFO_CUT_VER, // ODM_CUT_VERSION_E + ODM_CMNINFO_FAB_VER, // ODM_FAB_E + ODM_CMNINFO_RF_TYPE, // ODM_RF_PATH_E or ODM_RF_TYPE_E? + ODM_CMNINFO_RFE_TYPE, + ODM_CMNINFO_BOARD_TYPE, // ODM_BOARD_TYPE_E + ODM_CMNINFO_PACKAGE_TYPE, + ODM_CMNINFO_EXT_LNA, // TRUE + ODM_CMNINFO_5G_EXT_LNA, + ODM_CMNINFO_EXT_PA, + ODM_CMNINFO_5G_EXT_PA, + ODM_CMNINFO_GPA, + ODM_CMNINFO_APA, + ODM_CMNINFO_GLNA, + ODM_CMNINFO_ALNA, + ODM_CMNINFO_EXT_TRSW, + ODM_CMNINFO_PATCH_ID, //CUSTOMER ID + ODM_CMNINFO_BINHCT_TEST, + ODM_CMNINFO_BWIFI_TEST, + ODM_CMNINFO_SMART_CONCURRENT, + ODM_CMNINFO_DOMAIN_CODE_2G, + ODM_CMNINFO_DOMAIN_CODE_5G, + ODM_CMNINFO_IQKFWOFFLOAD, + //-----------HOOK BEFORE REG INIT-----------// + + + // + // Dynamic value: + // +//--------- POINTER REFERENCE-----------// + ODM_CMNINFO_MAC_PHY_MODE, // ODM_MAC_PHY_MODE_E + ODM_CMNINFO_TX_UNI, + ODM_CMNINFO_RX_UNI, + ODM_CMNINFO_WM_MODE, // ODM_WIRELESS_MODE_E + ODM_CMNINFO_BAND, // ODM_BAND_TYPE_E + ODM_CMNINFO_SEC_CHNL_OFFSET, // ODM_SEC_CHNL_OFFSET_E + ODM_CMNINFO_SEC_MODE, // ODM_SECURITY_E + ODM_CMNINFO_BW, // ODM_BW_E + ODM_CMNINFO_CHNL, + ODM_CMNINFO_FORCED_RATE, + + ODM_CMNINFO_DMSP_GET_VALUE, + ODM_CMNINFO_BUDDY_ADAPTOR, + ODM_CMNINFO_DMSP_IS_MASTER, + ODM_CMNINFO_SCAN, + ODM_CMNINFO_POWER_SAVING, + ODM_CMNINFO_ONE_PATH_CCA, // ODM_CCA_PATH_E + ODM_CMNINFO_DRV_STOP, + ODM_CMNINFO_PNP_IN, + ODM_CMNINFO_INIT_ON, + ODM_CMNINFO_ANT_TEST, + ODM_CMNINFO_NET_CLOSED, + //ODM_CMNINFO_RTSTA_AID, // For win driver only? + ODM_CMNINFO_FORCED_IGI_LB, + ODM_CMNINFO_P2P_LINK, + ODM_CMNINFO_FCS_MODE, + ODM_CMNINFO_IS1ANTENNA, + ODM_CMNINFO_RFDEFAULTPATH, +//--------- POINTER REFERENCE-----------// + +//------------CALL BY VALUE-------------// + ODM_CMNINFO_WIFI_DIRECT, + ODM_CMNINFO_WIFI_DISPLAY, + ODM_CMNINFO_LINK_IN_PROGRESS, + ODM_CMNINFO_LINK, + ODM_CMNINFO_STATION_STATE, + ODM_CMNINFO_RSSI_MIN, + ODM_CMNINFO_DBG_COMP, // u8Byte + ODM_CMNINFO_DBG_LEVEL, // u4Byte + ODM_CMNINFO_RA_THRESHOLD_HIGH, // u1Byte + ODM_CMNINFO_RA_THRESHOLD_LOW, // u1Byte + ODM_CMNINFO_RF_ANTENNA_TYPE, // u1Byte + ODM_CMNINFO_BT_ENABLED, + ODM_CMNINFO_BT_HS_CONNECT_PROCESS, + ODM_CMNINFO_BT_HS_RSSI, + ODM_CMNINFO_BT_OPERATION, + ODM_CMNINFO_BT_LIMITED_DIG, //Need to Limited Dig or not + ODM_CMNINFO_BT_DISABLE_EDCA, +#if(DM_ODM_SUPPORT_TYPE & ODM_AP) // for repeater mode add by YuChen 2014.06. +#ifdef UNIVERSAL_REPEATER + ODM_CMNINFO_VXD_LINK, +#endif +#endif + +//------------CALL BY VALUE-------------// + + // + // Dynamic ptr array hook itms. + // + ODM_CMNINFO_STA_STATUS, + ODM_CMNINFO_PHY_STATUS, + ODM_CMNINFO_MAC_STATUS, + + ODM_CMNINFO_MAX, + + +}ODM_CMNINFO_E; + +// +// 2011/10/20 MH Define ODM support ability. ODM_CMNINFO_ABILITY +// +typedef enum _ODM_Support_Ability_Definition +{ + // + // BB ODM section BIT 0-19 + // + ODM_BB_DIG = BIT0, + ODM_BB_RA_MASK = BIT1, + ODM_BB_DYNAMIC_TXPWR = BIT2, + ODM_BB_FA_CNT = BIT3, + ODM_BB_RSSI_MONITOR = BIT4, + ODM_BB_CCK_PD = BIT5, + ODM_BB_ANT_DIV = BIT6, + ODM_BB_PWR_SAVE = BIT7, + ODM_BB_PWR_TRAIN = BIT8, + ODM_BB_RATE_ADAPTIVE = BIT9, + ODM_BB_PATH_DIV = BIT10, + ODM_BB_PSD = BIT11, + ODM_BB_RXHP = BIT12, + ODM_BB_ADAPTIVITY = BIT13, + ODM_BB_CFO_TRACKING = BIT14, + ODM_BB_NHM_CNT = BIT15, + ODM_BB_PRIMARY_CCA = BIT16, + + // + // MAC DM section BIT 20-23 + // + ODM_MAC_EDCA_TURBO = BIT20, + ODM_MAC_EARLY_MODE = BIT21, + + // + // RF ODM section BIT 24-31 + // + ODM_RF_TX_PWR_TRACK = BIT24, + ODM_RF_RX_GAIN_TRACK = BIT25, + ODM_RF_CALIBRATION = BIT26, + +}ODM_ABILITY_E; + +// ODM_CMNINFO_INTERFACE +typedef enum tag_ODM_Support_Interface_Definition +{ + ODM_ITRF_PCIE = 0x1, + ODM_ITRF_USB = 0x2, + ODM_ITRF_SDIO = 0x4, + ODM_ITRF_ALL = 0x7, +}ODM_INTERFACE_E; + +// ODM_CMNINFO_IC_TYPE +typedef enum tag_ODM_Support_IC_Type_Definition +{ + ODM_RTL8192S = BIT0, + ODM_RTL8192C = BIT1, + ODM_RTL8192D = BIT2, + ODM_RTL8723A = BIT3, + ODM_RTL8188E = BIT4, + ODM_RTL8812 = BIT5, + ODM_RTL8821 = BIT6, + ODM_RTL8192E = BIT7, + ODM_RTL8723B = BIT8, + ODM_RTL8814A = BIT9, + ODM_RTL8881A = BIT10, + ODM_RTL8821B = BIT11, + ODM_RTL8822B = BIT12, + ODM_RTL8703B = BIT13 +}ODM_IC_TYPE_E; + +#define ODM_IC_11N_SERIES (ODM_RTL8192S|ODM_RTL8192C|ODM_RTL8192D|ODM_RTL8723A|ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8703B) +#define ODM_IC_11AC_SERIES (ODM_RTL8812|ODM_RTL8821|ODM_RTL8814A|ODM_RTL8881A|ODM_RTL8821B|ODM_RTL8822B) + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + +#ifdef RTK_AC_SUPPORT +#define ODM_IC_11AC_SERIES_SUPPORT 1 +#else +#define ODM_IC_11AC_SERIES_SUPPORT 0 +#endif + +#define ODM_IC_11N_SERIES_SUPPORT 1 +#define ODM_CONFIG_BT_COEXIST 0 + +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#define ODM_IC_11AC_SERIES_SUPPORT 1 +#define ODM_IC_11N_SERIES_SUPPORT 1 +#define ODM_CONFIG_BT_COEXIST 1 + +#else + +#if((RTL8192C_SUPPORT == 1) || (RTL8192D_SUPPORT == 1) || (RTL8723A_SUPPORT == 1) || (RTL8188E_SUPPORT == 1) ||\ +(RTL8723B_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8195A_SUPPORT == 1)) +#define ODM_IC_11N_SERIES_SUPPORT 1 +#define ODM_IC_11AC_SERIES_SUPPORT 0 +#else +#define ODM_IC_11N_SERIES_SUPPORT 0 +#define ODM_IC_11AC_SERIES_SUPPORT 1 +#endif + +#ifdef CONFIG_BT_COEXIST +#define ODM_CONFIG_BT_COEXIST 1 +#else +#define ODM_CONFIG_BT_COEXIST 0 +#endif + +#endif + + +//ODM_CMNINFO_CUT_VER +typedef enum tag_ODM_Cut_Version_Definition +{ + ODM_CUT_A = 0, + ODM_CUT_B = 1, + ODM_CUT_C = 2, + ODM_CUT_D = 3, + ODM_CUT_E = 4, + ODM_CUT_F = 5, + + ODM_CUT_I = 8, + ODM_CUT_J = 9, + ODM_CUT_K = 10, + ODM_CUT_TEST = 15, +}ODM_CUT_VERSION_E; + +// ODM_CMNINFO_FAB_VER +typedef enum tag_ODM_Fab_Version_Definition +{ + ODM_TSMC = 0, + ODM_UMC = 1, +}ODM_FAB_E; + +// ODM_CMNINFO_RF_TYPE +// +// For example 1T2R (A+AB = BIT0|BIT4|BIT5) +// +typedef enum tag_ODM_RF_Path_Bit_Definition +{ + ODM_RF_TX_A = BIT0, + ODM_RF_TX_B = BIT1, + ODM_RF_TX_C = BIT2, + ODM_RF_TX_D = BIT3, + ODM_RF_RX_A = BIT4, + ODM_RF_RX_B = BIT5, + ODM_RF_RX_C = BIT6, + ODM_RF_RX_D = BIT7, +}ODM_RF_PATH_E; + + +typedef enum tag_ODM_RF_Type_Definition +{ + ODM_1T1R = 0, + ODM_1T2R = 1, + ODM_2T2R = 2, + ODM_2T3R = 3, + ODM_2T4R = 4, + ODM_3T3R = 5, + ODM_3T4R = 6, + ODM_4T4R = 7, +}ODM_RF_TYPE_E; + + +// +// ODM Dynamic common info value definition +// + +//typedef enum _MACPHY_MODE_8192D{ +// SINGLEMAC_SINGLEPHY, +// DUALMAC_DUALPHY, +// DUALMAC_SINGLEPHY, +//}MACPHY_MODE_8192D,*PMACPHY_MODE_8192D; +// Above is the original define in MP driver. Please use the same define. THX. +typedef enum tag_ODM_MAC_PHY_Mode_Definition +{ + ODM_SMSP = 0, + ODM_DMSP = 1, + ODM_DMDP = 2, +}ODM_MAC_PHY_MODE_E; + + +typedef enum tag_BT_Coexist_Definition +{ + ODM_BT_BUSY = 1, + ODM_BT_ON = 2, + ODM_BT_OFF = 3, + ODM_BT_NONE = 4, +}ODM_BT_COEXIST_E; + +// ODM_CMNINFO_OP_MODE +typedef enum tag_Operation_Mode_Definition +{ + ODM_NO_LINK = BIT0, + ODM_LINK = BIT1, + ODM_SCAN = BIT2, + ODM_POWERSAVE = BIT3, + ODM_AP_MODE = BIT4, + ODM_CLIENT_MODE = BIT5, + ODM_AD_HOC = BIT6, + ODM_WIFI_DIRECT = BIT7, + ODM_WIFI_DISPLAY = BIT8, +}ODM_OPERATION_MODE_E; + +// ODM_CMNINFO_WM_MODE +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_CE)) +typedef enum tag_Wireless_Mode_Definition +{ + ODM_WM_UNKNOW = 0x0, + ODM_WM_B = BIT0, + ODM_WM_G = BIT1, + ODM_WM_A = BIT2, + ODM_WM_N24G = BIT3, + ODM_WM_N5G = BIT4, + ODM_WM_AUTO = BIT5, + ODM_WM_AC = BIT6, +}ODM_WIRELESS_MODE_E; +#else +typedef enum tag_Wireless_Mode_Definition +{ + ODM_WM_UNKNOWN = 0x00, + ODM_WM_A = BIT0, + ODM_WM_B = BIT1, + ODM_WM_G = BIT2, + ODM_WM_AUTO = BIT3, + ODM_WM_N24G = BIT4, + ODM_WM_N5G = BIT5, + ODM_WM_AC_5G = BIT6, + ODM_WM_AC_24G = BIT7, + ODM_WM_AC_ONLY = BIT8, + ODM_WM_MAX = BIT9 +}ODM_WIRELESS_MODE_E; +#endif + +// ODM_CMNINFO_BAND +typedef enum tag_Band_Type_Definition +{ + ODM_BAND_2_4G = 0, + ODM_BAND_5G, + ODM_BAND_ON_BOTH, + ODM_BANDMAX + +}ODM_BAND_TYPE_E; + +// ODM_CMNINFO_SEC_CHNL_OFFSET +typedef enum tag_Secondary_Channel_Offset_Definition +{ + ODM_DONT_CARE = 0, + ODM_BELOW = 1, + ODM_ABOVE = 2 +}ODM_SEC_CHNL_OFFSET_E; + +// ODM_CMNINFO_SEC_MODE +typedef enum tag_Security_Definition +{ + ODM_SEC_OPEN = 0, + ODM_SEC_WEP40 = 1, + ODM_SEC_TKIP = 2, + ODM_SEC_RESERVE = 3, + ODM_SEC_AESCCMP = 4, + ODM_SEC_WEP104 = 5, + ODM_WEP_WPA_MIXED = 6, // WEP + WPA + ODM_SEC_SMS4 = 7, +}ODM_SECURITY_E; + +// ODM_CMNINFO_BW +typedef enum tag_Bandwidth_Definition +{ + ODM_BW20M = 0, + ODM_BW40M = 1, + ODM_BW80M = 2, + ODM_BW160M = 3, + ODM_BW10M = 4, +}ODM_BW_E; + + +// ODM_CMNINFO_BOARD_TYPE +// For non-AC-series IC , ODM_BOARD_5G_EXT_PA and ODM_BOARD_5G_EXT_LNA are ignored +// For AC-series IC, external PA & LNA can be indivisuallly added on 2.4G and/or 5G +typedef enum tag_Board_Definition +{ + ODM_BOARD_DEFAULT = 0, // The DEFAULT case. + ODM_BOARD_MINICARD = BIT(0), // 0 = non-mini card, 1= mini card. + ODM_BOARD_SLIM = BIT(1), // 0 = non-slim card, 1 = slim card + ODM_BOARD_BT = BIT(2), // 0 = without BT card, 1 = with BT + ODM_BOARD_EXT_PA = BIT(3), // 0 = no 2G ext-PA, 1 = existing 2G ext-PA + ODM_BOARD_EXT_LNA = BIT(4), // 0 = no 2G ext-LNA, 1 = existing 2G ext-LNA + ODM_BOARD_EXT_TRSW = BIT(5), // 0 = no ext-TRSW, 1 = existing ext-TRSW + ODM_BOARD_EXT_PA_5G = BIT(6), // 0 = no 5G ext-PA, 1 = existing 5G ext-PA + ODM_BOARD_EXT_LNA_5G= BIT(7), // 0 = no 5G ext-LNA, 1 = existing 5G ext-LNA +}ODM_BOARD_TYPE_E; + +typedef enum tag_ODM_Package_Definition +{ + ODM_PACKAGE_DEFAULT = 0, + ODM_PACKAGE_QFN68 = BIT(0), + ODM_PACKAGE_TFBGA90 = BIT(1), + ODM_PACKAGE_TFBGA79 = BIT(2), +}ODM_Package_TYPE_E; + +typedef enum tag_ODM_TYPE_GPA_Definition +{ + TYPE_GPA0 = 0, + TYPE_GPA1 = BIT(1)|BIT(0) +}ODM_TYPE_GPA_E; + +typedef enum tag_ODM_TYPE_APA_Definition +{ + TYPE_APA0 = 0, + TYPE_APA1 = BIT(1)|BIT(0) +}ODM_TYPE_APA_E; + +typedef enum tag_ODM_TYPE_GLNA_Definition +{ + TYPE_GLNA0 = 0, + TYPE_GLNA1 = BIT(2)|BIT(0), + TYPE_GLNA2 = BIT(3)|BIT(1), + TYPE_GLNA3 = BIT(3)|BIT(2)|BIT(1)|BIT(0) +}ODM_TYPE_GLNA_E; + +typedef enum tag_ODM_TYPE_ALNA_Definition +{ + TYPE_ALNA0 = 0, + TYPE_ALNA1 = BIT(2)|BIT(0), + TYPE_ALNA2 = BIT(3)|BIT(1), + TYPE_ALNA3 = BIT(3)|BIT(2)|BIT(1)|BIT(0) +}ODM_TYPE_ALNA_E; + +// ODM_CMNINFO_ONE_PATH_CCA +typedef enum tag_CCA_Path +{ + ODM_CCA_2R = 0, + ODM_CCA_1R_A = 1, + ODM_CCA_1R_B = 2, +}ODM_CCA_PATH_E; + + +typedef struct _ODM_RA_Info_ +{ + u1Byte RateID; + u4Byte RateMask; + u4Byte RAUseRate; + u1Byte RateSGI; + u1Byte RssiStaRA; + u1Byte PreRssiStaRA; + u1Byte SGIEnable; + u1Byte DecisionRate; + u1Byte PreRate; + u1Byte HighestRate; + u1Byte LowestRate; + u4Byte NscUp; + u4Byte NscDown; + u2Byte RTY[5]; + u4Byte TOTAL; + u2Byte DROP; + u1Byte Active; + u2Byte RptTime; + u1Byte RAWaitingCounter; + u1Byte RAPendingCounter; +#if 1 //POWER_TRAINING_ACTIVE == 1 // For compile pass only~! + u1Byte PTActive; // on or off + u1Byte PTTryState; // 0 trying state, 1 for decision state + u1Byte PTStage; // 0~6 + u1Byte PTStopCount; //Stop PT counter + u1Byte PTPreRate; // if rate change do PT + u1Byte PTPreRssi; // if RSSI change 5% do PT + u1Byte PTModeSS; // decide whitch rate should do PT + u1Byte RAstage; // StageRA, decide how many times RA will be done between PT + u1Byte PTSmoothFactor; +#endif +} ODM_RA_INFO_T,*PODM_RA_INFO_T; + +//Remove struct PATHDIV_PARA to odm_PathDiv.h + +//move to PowerTracking.h by YuChen + +// +// ODM Dynamic common info value definition +// + +typedef struct _FAST_ANTENNA_TRAINNING_ +{ + u1Byte Bssid[6]; + u1Byte antsel_rx_keep_0; + u1Byte antsel_rx_keep_1; + u1Byte antsel_rx_keep_2; + u1Byte antsel_rx_keep_3; + u4Byte antSumRSSI[7]; + u4Byte antRSSIcnt[7]; + u4Byte antAveRSSI[7]; + u1Byte FAT_State; + u4Byte TrainIdx; + u1Byte antsel_a[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte antsel_b[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte antsel_c[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte MainAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte AuxAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte MainAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte AuxAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte RxIdleAnt; + BOOLEAN bBecomeLinked; + u4Byte MinMaxRSSI; + u1Byte idx_AntDiv_counter_2G; + u1Byte idx_AntDiv_counter_5G; + u4Byte AntDiv_2G_5G; + u4Byte CCK_counter_main; + u4Byte CCK_counter_aux; + u4Byte OFDM_counter_main; + u4Byte OFDM_counter_aux; + + + u4Byte CCK_CtrlFrame_Cnt_main; + u4Byte CCK_CtrlFrame_Cnt_aux; + u4Byte OFDM_CtrlFrame_Cnt_main; + u4Byte OFDM_CtrlFrame_Cnt_aux; + u4Byte MainAnt_CtrlFrame_Sum; + u4Byte AuxAnt_CtrlFrame_Sum; + u4Byte MainAnt_CtrlFrame_Cnt; + u4Byte AuxAnt_CtrlFrame_Cnt; + +}FAT_T,*pFAT_T; + +typedef enum _FAT_STATE +{ + FAT_NORMAL_STATE = 0, + FAT_TRAINING_STATE = 1, +}FAT_STATE_E, *PFAT_STATE_E; + +typedef enum _ANT_DIV_TYPE +{ + NO_ANTDIV = 0xFF, + CG_TRX_HW_ANTDIV = 0x01, + CGCS_RX_HW_ANTDIV = 0x02, + FIXED_HW_ANTDIV = 0x03, + CG_TRX_SMART_ANTDIV = 0x04, + CGCS_RX_SW_ANTDIV = 0x05, + S0S1_SW_ANTDIV = 0x06 //8723B intrnal switch S0 S1 +}ANT_DIV_TYPE_E, *PANT_DIV_TYPE_E; + + +typedef struct _ODM_PATH_DIVERSITY_ +{ + u1Byte RespTxPath; + u1Byte PathSel[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathA_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathB_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathA_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathB_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; +}PATHDIV_T, *pPATHDIV_T; + + +typedef enum _BASEBAND_CONFIG_PHY_REG_PG_VALUE_TYPE{ + PHY_REG_PG_RELATIVE_VALUE = 0, + PHY_REG_PG_EXACT_VALUE = 1 +} PHY_REG_PG_TYPE; + + +// +// Antenna detection information from single tone mechanism, added by Roger, 2012.11.27. +// +typedef struct _ANT_DETECTED_INFO{ + BOOLEAN bAntDetected; + u4Byte dBForAntA; + u4Byte dBForAntB; + u4Byte dBForAntO; +}ANT_DETECTED_INFO, *PANT_DETECTED_INFO; + +// +// 2011/09/22 MH Copy from SD4 defined structure. We use to support PHY DM integration. +// +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if (RT_PLATFORM != PLATFORM_LINUX) +typedef +#endif +struct DM_Out_Source_Dynamic_Mechanism_Structure +#else// for AP,ADSL,CE Team +typedef struct DM_Out_Source_Dynamic_Mechanism_Structure +#endif +{ + //RT_TIMER FastAntTrainingTimer; + // + // Add for different team use temporarily + // + PADAPTER Adapter; // For CE/NIC team + prtl8192cd_priv priv; // For AP/ADSL team + // WHen you use Adapter or priv pointer, you must make sure the pointer is ready. + BOOLEAN odm_ready; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + rtl8192cd_priv fake_priv; +#endif +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + // ADSL_AP_BUILD_WORKAROUND + ADAPTER fake_adapter; +#endif + + PHY_REG_PG_TYPE PhyRegPgValueType; + u1Byte PhyRegPgVersion; + + u8Byte DebugComponents; + u4Byte DebugLevel; + + u4Byte NumQryPhyStatusAll; //CCK + OFDM + u4Byte LastNumQryPhyStatusAll; + u4Byte RxPWDBAve; + BOOLEAN MPDIG_2G; //off MPDIG + u1Byte Times_2G; + +//------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------// + BOOLEAN bCckHighPower; + u1Byte RFPathRxEnable; // ODM_CMNINFO_RFPATH_ENABLE + u1Byte ControlChannel; +//------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------// + +//--------REMOVED COMMON INFO----------// + //u1Byte PseudoMacPhyMode; + //BOOLEAN *BTCoexist; + //BOOLEAN PseudoBtCoexist; + //u1Byte OPMode; + //BOOLEAN bAPMode; + //BOOLEAN bClientMode; + //BOOLEAN bAdHocMode; + //BOOLEAN bSlaveOfDMSP; +//--------REMOVED COMMON INFO----------// + + +//1 COMMON INFORMATION + + // + // Init Value + // +//-----------HOOK BEFORE REG INIT-----------// + // ODM Platform info AP/ADSL/CE/MP = 1/2/3/4 + u1Byte SupportPlatform; + // ODM Support Ability DIG/RATR/TX_PWR_TRACK/ ¡K¡K = 1/2/3/¡K + u4Byte SupportAbility; + // ODM PCIE/USB/SDIO = 1/2/3 + u1Byte SupportInterface; + // ODM composite or independent. Bit oriented/ 92C+92D+ .... or any other type = 1/2/3/... + u4Byte SupportICType; + // Cut Version TestChip/A-cut/B-cut... = 0/1/2/3/... + u1Byte CutVersion; + // Fab Version TSMC/UMC = 0/1 + u1Byte FabVersion; + // RF Type 4T4R/3T3R/2T2R/1T2R/1T1R/... + u1Byte RFType; + u1Byte RFEType; + // Board Type Normal/HighPower/MiniCard/SLIM/Combo/... = 0/1/2/3/4/... + u1Byte BoardType; + u1Byte PackageType; + u1Byte TypeGLNA; + u1Byte TypeGPA; + u1Byte TypeALNA; + u1Byte TypeAPA; + // with external LNA NO/Yes = 0/1 + u1Byte ExtLNA; + u1Byte ExtLNA5G; + // with external PA NO/Yes = 0/1 + u1Byte ExtPA; + u1Byte ExtPA5G; + // with external TRSW NO/Yes = 0/1 + u1Byte ExtTRSW; + u1Byte PatchID; //Customer ID + BOOLEAN bInHctTest; + BOOLEAN bWIFITest; + + BOOLEAN bDualMacSmartConcurrent; + u4Byte BK_SupportAbility; + u1Byte AntDivType; + + u1Byte odm_Regulation2_4G; + u1Byte odm_Regulation5G; + u1Byte IQKFWOffload; +//-----------HOOK BEFORE REG INIT-----------// + + // + // Dynamic Value + // +//--------- POINTER REFERENCE-----------// + + u1Byte u1Byte_temp; + BOOLEAN BOOLEAN_temp; + PADAPTER PADAPTER_temp; + + // MAC PHY Mode SMSP/DMSP/DMDP = 0/1/2 + u1Byte *pMacPhyMode; + //TX Unicast byte count + u8Byte *pNumTxBytesUnicast; + //RX Unicast byte count + u8Byte *pNumRxBytesUnicast; + // Wireless mode B/G/A/N = BIT0/BIT1/BIT2/BIT3 + u1Byte *pWirelessMode; //ODM_WIRELESS_MODE_E + // Frequence band 2.4G/5G = 0/1 + u1Byte *pBandType; + // Secondary channel offset don't_care/below/above = 0/1/2 + u1Byte *pSecChOffset; + // Security mode Open/WEP/AES/TKIP = 0/1/2/3 + u1Byte *pSecurity; + // BW info 20M/40M/80M = 0/1/2 + u1Byte *pBandWidth; + // Central channel location Ch1/Ch2/.... + u1Byte *pChannel; //central channel number + BOOLEAN DPK_Done; + // Common info for 92D DMSP + + BOOLEAN *pbGetValueFromOtherMac; + PADAPTER *pBuddyAdapter; + BOOLEAN *pbMasterOfDMSP; //MAC0: master, MAC1: slave + // Common info for Status + BOOLEAN *pbScanInProcess; + BOOLEAN *pbPowerSaving; + // CCA Path 2-path/path-A/path-B = 0/1/2; using ODM_CCA_PATH_E. + u1Byte *pOnePathCCA; + //pMgntInfo->AntennaTest + u1Byte *pAntennaTest; + BOOLEAN *pbNet_closed; + //u1Byte *pAidMap; + u1Byte *pu1ForcedIgiLb; + BOOLEAN *pIsFcsModeEnable; +//--------- For 8723B IQK-----------// + BOOLEAN *pIs1Antenna; + u1Byte *pRFDefaultPath; + // 0:S1, 1:S0 + +//--------- POINTER REFERENCE-----------// + pu2Byte pForcedDataRate; +//------------CALL BY VALUE-------------// + BOOLEAN bLinkInProcess; + BOOLEAN bWIFI_Direct; + BOOLEAN bWIFI_Display; + BOOLEAN bLinked; + BOOLEAN bsta_state; + u1Byte RSSI_Min; + u1Byte InterfaceIndex; // Add for 92D dual MAC: 0--Mac0 1--Mac1 + BOOLEAN bIsMPChip; + BOOLEAN bOneEntryOnly; + BOOLEAN mp_mode; + // Common info for BTDM + BOOLEAN bBtEnabled; // BT is enabled + BOOLEAN bBtConnectProcess; // BT HS is under connection progress. + u1Byte btHsRssi; // BT HS mode wifi rssi value. + BOOLEAN bBtHsOperation; // BT HS mode is under progress + BOOLEAN bBtDisableEdcaTurbo; // Under some condition, don't enable the EDCA Turbo + BOOLEAN bBtLimitedDig; // BT is busy. +//------------CALL BY VALUE-------------// + u1Byte RSSI_A; + u1Byte RSSI_B; + u1Byte RSSI_C; + u1Byte RSSI_D; + u8Byte RSSI_TRSW; + u8Byte RSSI_TRSW_H; + u8Byte RSSI_TRSW_L; + u8Byte RSSI_TRSW_iso; + + u1Byte RxRate; + BOOLEAN bNoisyState; + u1Byte TxRate; + u1Byte LinkedInterval; + u1Byte preChannel; + u4Byte TxagcOffsetValueA; + BOOLEAN IsTxagcOffsetPositiveA; + u4Byte TxagcOffsetValueB; + BOOLEAN IsTxagcOffsetPositiveB; + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u4Byte BbSwingOffsetA; + BOOLEAN IsBbSwingOffsetPositiveA; + u4Byte BbSwingOffsetB; + BOOLEAN IsBbSwingOffsetPositiveB; + s1Byte TH_L2H_ini; + s1Byte TH_EDCCA_HL_diff; + s1Byte IGI_Base; + u1Byte IGI_target; + BOOLEAN ForceEDCCA; + u1Byte AdapEn_RSSI; + s1Byte Force_TH_H; + s1Byte Force_TH_L; + u1Byte IGI_LowerBound; + u1Byte antdiv_rssi; + u1Byte AntType; + u1Byte pre_AntType; + u1Byte antdiv_period; + u1Byte antdiv_select; + u1Byte NdpaPeriod; + BOOLEAN H2C_RARpt_connect; + + // add by Yu Cehn for adaptivtiy + BOOLEAN adaptivity_flag; + u1Byte tolerance_cnt; + u8Byte NHMCurTxOkcnt; + u8Byte NHMCurRxOkcnt; + u8Byte NHMLastTxOkcnt; + u8Byte NHMLastRxOkcnt; + u1Byte NHMWait; + s1Byte H2L_lb; + s1Byte L2H_lb; + u1Byte Adaptivity_IGI_upper; + u2Byte NHM_cnt_0; + u2Byte NHM_cnt_1; + BOOLEAN Carrier_Sense_enable; + BOOLEAN bFirstLink; + BOOLEAN bCheck; + BOOLEAN EDCCA_enable_state; + BOOLEAN NHM_enable; + BOOLEAN DynamicLinkAdaptivity; + BOOLEAN bAdaOn; + + ODM_NOISE_MONITOR noise_level;//[ODM_MAX_CHANNEL_NUM]; + // + //2 Define STA info. + // _ODM_STA_INFO + // 2012/01/12 MH For MP, we need to reduce one array pointer for default port.?? + PSTA_INFO_T pODM_StaInfo[ODM_ASSOCIATE_ENTRY_NUM]; + +#if (RATE_ADAPTIVE_SUPPORT == 1) + u2Byte CurrminRptTime; + ODM_RA_INFO_T RAInfo[ODM_ASSOCIATE_ENTRY_NUM]; //See HalMacID support +#endif + // + // 2012/02/14 MH Add to share 88E ra with other SW team. + // We need to colelct all support abilit to a proper area. + // + BOOLEAN RaSupport88E; + + // Define ........... + + // Latest packet phy info (ODM write) + ODM_PHY_DBG_INFO_T PhyDbgInfo; + //PHY_INFO_88E PhyInfo; + + // Latest packet phy info (ODM write) + ODM_MAC_INFO *pMacInfo; + //MAC_INFO_88E MacInfo; + + // Different Team independt structure?? + + // + //TX_RTP_CMN TX_retrpo; + //TX_RTP_88E TX_retrpo; + //TX_RTP_8195 TX_retrpo; + + // + //ODM Structure + // + FAT_T DM_FatTable; + DIG_T DM_DigTable; + PS_T DM_PSTable; + Pri_CCA_T DM_PriCCA; +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + RXHP_T DM_RXHP_Table; +#endif + RA_T DM_RA_Table; + FALSE_ALARM_STATISTICS FalseAlmCnt; + FALSE_ALARM_STATISTICS FlaseAlmCntBuddyAdapter; + //#ifdef CONFIG_ANTENNA_DIVERSITY + SWAT_T DM_SWAT_Table; + BOOLEAN RSSI_test; + CFO_TRACKING DM_CfoTrack; + ACS DM_ACS; + //#endif + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + //Path Div Struct + PATHDIV_PARA pathIQK; +#endif + + EDCA_T DM_EDCA_Table; + u4Byte WMMEDCA_BE; + PATHDIV_T DM_PathDiv; + // Copy from SD4 structure + // + // ================================================== + // + + //common + //u1Byte DM_Type; + //u1Byte PSD_Report_RXHP[80]; // Add By Gary + //u1Byte PSD_func_flag; // Add By Gary + //for DIG + //u1Byte bDMInitialGainEnable; + //u1Byte binitialized; // for dm_initial_gain_Multi_STA use. + //for Antenna diversity + //u8 AntDivCfg;// 0:OFF , 1:ON, 2:by efuse + //PSTA_INFO_T RSSI_target; + + BOOLEAN *pbDriverStopped; + BOOLEAN *pbDriverIsGoingToPnpSetPowerSleep; + BOOLEAN *pinit_adpt_in_progress; + + //PSD + BOOLEAN bUserAssignLevel; + RT_TIMER PSDTimer; + u1Byte RSSI_BT; //come from BT + BOOLEAN bPSDinProcess; + BOOLEAN bPSDactive; + BOOLEAN bDMInitialGainEnable; + + //MPT DIG + RT_TIMER MPT_DIGTimer; + + //for rate adaptive, in fact, 88c/92c fw will handle this + u1Byte bUseRAMask; + + ODM_RATE_ADAPTIVE RateAdaptive; + + ANT_DETECTED_INFO AntDetectedInfo; // Antenna detected information for RSSI tool + + ODM_RF_CAL_T RFCalibrateInfo; + + // + // TX power tracking + // + u1Byte BbSwingIdxOfdm[MAX_RF_PATH]; + u1Byte BbSwingIdxOfdmCurrent; + u1Byte BbSwingIdxOfdmBase[MAX_RF_PATH]; + BOOLEAN BbSwingFlagOfdm; + u1Byte BbSwingIdxCck; + u1Byte BbSwingIdxCckCurrent; + u1Byte BbSwingIdxCckBase; + u1Byte DefaultOfdmIndex; + u1Byte DefaultCckIndex; + BOOLEAN BbSwingFlagCck; + + s1Byte Absolute_OFDMSwingIdx[MAX_RF_PATH]; + s1Byte Remnant_OFDMSwingIdx[MAX_RF_PATH]; + s1Byte Remnant_CCKSwingIdx; + s1Byte Modify_TxAGC_Value; //Remnat compensate value at TxAGC + BOOLEAN Modify_TxAGC_Flag_PathA; + BOOLEAN Modify_TxAGC_Flag_PathB; + BOOLEAN Modify_TxAGC_Flag_PathC; + BOOLEAN Modify_TxAGC_Flag_PathD; + BOOLEAN Modify_TxAGC_Flag_PathA_CCK; + + s1Byte KfreeOffset[MAX_RF_PATH]; + + // + // Dynamic ATC switch + // + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + // + // Power Training + // + BOOLEAN bDisablePowerTraining; + u1Byte ForcePowerTrainingState; + BOOLEAN bChangeState; + u4Byte PT_score; + u8Byte OFDM_RX_Cnt; + u8Byte CCK_RX_Cnt; +#endif + + // + // ODM system resource. + // + + // ODM relative time. + RT_TIMER PathDivSwitchTimer; + //2011.09.27 add for Path Diversity + RT_TIMER CCKPathDiversityTimer; + RT_TIMER FastAntTrainingTimer; + + // ODM relative workitem. +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if USE_WORKITEM + RT_WORK_ITEM PathDivSwitchWorkitem; + RT_WORK_ITEM CCKPathDiversityWorkitem; + RT_WORK_ITEM FastAntTrainingWorkitem; + RT_WORK_ITEM MPT_DIGWorkitem; + RT_WORK_ITEM RaRptWorkitem; + #endif +#endif + + #if (BEAMFORMING_SUPPORT == 1) + RT_BEAMFORMING_INFO BeamformingInfo; + #endif + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + +#if (RT_PLATFORM != PLATFORM_LINUX) +} DM_ODM_T, *PDM_ODM_T; // DM_Dynamic_Mechanism_Structure +#else +}; +#endif + +#else// for AP,ADSL,CE Team +} DM_ODM_T, *PDM_ODM_T; // DM_Dynamic_Mechanism_Structure +#endif + + + +#if 1 //92c-series +#define ODM_RF_PATH_MAX 2 +#else //jaguar - series +#define ODM_RF_PATH_MAX 4 +#endif + +typedef enum _PhyDM_Structure_Type{ + PHYDM_FALSEALMCNT, + PHYDM_CFOTRACK, + PHYDM_ROMINFO, + +}PhyDM_Structure_Type; + +typedef enum _ODM_RF_RADIO_PATH { + ODM_RF_PATH_A = 0, //Radio Path A + ODM_RF_PATH_B = 1, //Radio Path B + ODM_RF_PATH_C = 2, //Radio Path C + ODM_RF_PATH_D = 3, //Radio Path D + ODM_RF_PATH_AB, + ODM_RF_PATH_AC, + ODM_RF_PATH_AD, + ODM_RF_PATH_BC, + ODM_RF_PATH_BD, + ODM_RF_PATH_CD, + ODM_RF_PATH_ABC, + ODM_RF_PATH_ACD, + ODM_RF_PATH_BCD, + ODM_RF_PATH_ABCD, + // ODM_RF_PATH_MAX, //Max RF number 90 support +} ODM_RF_RADIO_PATH_E, *PODM_RF_RADIO_PATH_E; + + typedef enum _ODM_RF_CONTENT{ + odm_radioa_txt = 0x1000, + odm_radiob_txt = 0x1001, + odm_radioc_txt = 0x1002, + odm_radiod_txt = 0x1003 +} ODM_RF_CONTENT; + +typedef enum _ODM_BB_Config_Type{ + CONFIG_BB_PHY_REG, + CONFIG_BB_AGC_TAB, + CONFIG_BB_AGC_TAB_2G, + CONFIG_BB_AGC_TAB_5G, + CONFIG_BB_PHY_REG_PG, + CONFIG_BB_PHY_REG_MP, + CONFIG_BB_AGC_TAB_DIFF, +} ODM_BB_Config_Type, *PODM_BB_Config_Type; + +typedef enum _ODM_RF_Config_Type{ + CONFIG_RF_RADIO, + CONFIG_RF_TXPWR_LMT, +} ODM_RF_Config_Type, *PODM_RF_Config_Type; + +typedef enum _ODM_FW_Config_Type{ + CONFIG_FW_NIC, + CONFIG_FW_NIC_2, + CONFIG_FW_AP, + CONFIG_FW_MP, + CONFIG_FW_WoWLAN, + CONFIG_FW_WoWLAN_2, + CONFIG_FW_AP_WoWLAN, + CONFIG_FW_BT, +} ODM_FW_Config_Type; + +// Status code +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +typedef enum _RT_STATUS{ + RT_STATUS_SUCCESS, + RT_STATUS_FAILURE, + RT_STATUS_PENDING, + RT_STATUS_RESOURCE, + RT_STATUS_INVALID_CONTEXT, + RT_STATUS_INVALID_PARAMETER, + RT_STATUS_NOT_SUPPORT, + RT_STATUS_OS_API_FAILED, +}RT_STATUS,*PRT_STATUS; +#endif // end of RT_STATUS definition + +#ifdef REMOVE_PACK +#pragma pack() +#endif + +//#include "odm_function.h" + +//3=========================================================== +//3 DIG +//3=========================================================== + +//Remove DIG by Yuchen + +//3=========================================================== +//3 AGC RX High Power Mode +//3=========================================================== +#define LNA_Low_Gain_1 0x64 +#define LNA_Low_Gain_2 0x5A +#define LNA_Low_Gain_3 0x58 + +#define FA_RXHP_TH1 5000 +#define FA_RXHP_TH2 1500 +#define FA_RXHP_TH3 800 +#define FA_RXHP_TH4 600 +#define FA_RXHP_TH5 500 + +//3=========================================================== +//3 EDCA +//3=========================================================== + +//3=========================================================== +//3 Dynamic Tx Power +//3=========================================================== +//Dynamic Tx Power Control Threshold + +//Remove By YuChen + +//3=========================================================== +//3 Tx Power Tracking +//3=========================================================== +#if 0 //mask this, since these have been defined in typdef.h, vivi +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#endif + + +//3=========================================================== +//3 Rate Adaptive +//3=========================================================== +//Remove to odm_RaInfo.h by RS_James + +//3=========================================================== +//3 BB Power Save +//3=========================================================== + +typedef enum tag_1R_CCA_Type_Definition +{ + CCA_1R =0, + CCA_2R = 1, + CCA_MAX = 2, +}DM_1R_CCA_E; + +typedef enum tag_RF_Type_Definition +{ + RF_Save =0, + RF_Normal = 1, + RF_MAX = 2, +}DM_RF_E; + +//3=========================================================== +//3 Antenna Diversity +//3=========================================================== +typedef enum tag_SW_Antenna_Switch_Definition +{ + Antenna_A = 1, + Antenna_B = 2, + Antenna_MAX = 3, +}DM_SWAS_E; + + +// Maximal number of antenna detection mechanism needs to perform, added by Roger, 2011.12.28. +#define MAX_ANTENNA_DETECTION_CNT 10 + +// +// Extern Global Variables. +// +//remove PT by YuChen +// +// check Sta pointer valid or not +// +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#define IS_STA_VALID(pSta) (pSta && pSta->expire_to) +#elif (DM_ODM_SUPPORT_TYPE & ODM_WIN) +#define IS_STA_VALID(pSta) (pSta && pSta->bUsed) +#else +#define IS_STA_VALID(pSta) (pSta) +#endif +// 20100514 Joseph: Add definition for antenna switching test after link. +// This indicates two different the steps. +// In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. +// In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK +// with original RSSI to determine if it is necessary to switch antenna. +#define SWAW_STEP_PEAK 0 +#define SWAW_STEP_DETERMINE 1 + +//Remove DIG by yuchen + + + + +//Remove BB power saving by Yuchen + + + + + +//ODM_RAStateCheck() Remove by RS_James + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_AP|ODM_ADSL)) +//============================================================ +// function prototype +//============================================================ +//#define DM_ChangeDynamicInitGainThresh ODM_ChangeDynamicInitGainThresh +//void ODM_ChangeDynamicInitGainThresh(IN PADAPTER pAdapter, +// IN INT32 DM_Type, +// IN INT32 DM_Value); + +//Remove DIG by yuchen + + +BOOLEAN +ODM_CheckPowerStatus( + IN PADAPTER Adapter + ); + + +//Remove ODM_RateAdaptiveStateApInit() by RS_James + +//Remove Edca by YuChen + +#endif + +#if((DM_ODM_SUPPORT_TYPE==ODM_WIN)||(DM_ODM_SUPPORT_TYPE==ODM_CE)) + +u4Byte ConvertTo_dB(u4Byte Value); + +u4Byte +GetPSDData( + PDM_ODM_T pDM_Odm, + unsigned int point, + u1Byte initial_gain_psd); + +#endif + +//Remove ODM_Get_Rate_Bitmap() by RS_James + + +#if (BEAMFORMING_SUPPORT == 1) +BEAMFORMING_CAP +Beamforming_GetEntryBeamCapByMacId( + IN PMGNT_INFO pMgntInfo, + IN u1Byte MacId + ); +#endif + +VOID +ODM_DMInit( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_DMReset( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_DMWatchdog( + IN PDM_ODM_T pDM_Odm // For common use in the future + ); + +VOID +ODM_CmnInfoInit( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN u4Byte Value + ); + +VOID +ODM_CmnInfoHook( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN PVOID pValue + ); + +VOID +ODM_CmnInfoPtrArrayHook( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN u2Byte Index, + IN PVOID pValue + ); + +VOID +ODM_CmnInfoUpdate( + IN PDM_ODM_T pDM_Odm, + IN u4Byte CmnInfo, + IN u8Byte Value + ); + +VOID +ODM_InitAllTimers( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_CancelAllTimers( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_ReleaseAllTimers( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_ResetIQKResult( + IN PDM_ODM_T pDM_Odm + ); + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID ODM_InitAllWorkItems(IN PDM_ODM_T pDM_Odm ); +VOID ODM_FreeAllWorkItems(IN PDM_ODM_T pDM_Odm ); + + +//===========================================// +// Neil Chen----2011--06--15-- + +//3 Path Diversity +//=========================================================== + +#define TP_MODE 0 +#define RSSI_MODE 1 +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 + +//#define PATHDIV_ENABLE 1 + +//#define dm_PathDiv_RSSI_Check ODM_PathDivChkPerPktRssi + +u8Byte +PlatformDivision64( + IN u8Byte x, + IN u8Byte y +); + + +// 20100514 Joseph: Add definition for antenna switching test after link. +// This indicates two different the steps. +// In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. +// In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK +// with original RSSI to determine if it is necessary to switch antenna. +#define SWAW_STEP_PEAK 0 +#define SWAW_STEP_DETERMINE 1 + +//==================================================== +//3 PathDiV End +//==================================================== + +//#define PathDivCheckBeforeLink8192C ODM_PathDiversityBeforeLink92C + +#define DM_ChangeDynamicInitGainThresh ODM_ChangeDynamicInitGainThresh +//void ODM_ChangeDynamicInitGainThresh(IN PADAPTER pAdapter, +// IN INT32 DM_Type, +// IN INT32 DM_Value); +// + +typedef enum tag_DIG_Connect_Definition +{ + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MultiSTA_DISCONNECT = 3, + DIG_MultiSTA_CONNECT = 4, + DIG_CONNECT_MAX +}DM_DIG_CONNECT_E; + + +// +// 2012/01/12 MH Check afapter status. Temp fix BSOD. +// +#define HAL_ADAPTER_STS_CHK(pDM_Odm)\ + if (pDM_Odm->Adapter == NULL)\ + {\ + return;\ + }\ + + +// +// For new definition in MP temporarily fro power tracking, +// +#define odm_TXPowerTrackingDirectCall(_Adapter) \ + IS_HARDWARE_TYPE_8192D(_Adapter) ? odm_TXPowerTrackingCallback_ThermalMeter_92D(_Adapter) : \ + IS_HARDWARE_TYPE_8192C(_Adapter) ? odm_TXPowerTrackingCallback_ThermalMeter_92C(_Adapter) : \ + IS_HARDWARE_TYPE_8723A(_Adapter) ? odm_TXPowerTrackingCallback_ThermalMeter_8723A(_Adapter) :\ + ODM_TXPowerTrackingCallback_ThermalMeter(_Adapter) + + + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN |ODM_CE)) + +VOID +ODM_SingleDualAntennaDefaultSetting( + IN PDM_ODM_T pDM_Odm + ); + +BOOLEAN +ODM_SingleDualAntennaDetection( + IN PDM_ODM_T pDM_Odm, + IN u1Byte mode + ); + +#endif // #if((DM_ODM_SUPPORT_TYPE==ODM_WIN)||(DM_ODM_SUPPORT_TYPE==ODM_CE)) +VOID +ODM_UpdateNoisyState( + IN PDM_ODM_T pDM_Odm, + IN BOOLEAN bNoisyStateFromC2H +); + +u4Byte +Set_RA_DM_Ratrbitmap_by_Noisy( + IN PDM_ODM_T pDM_Odm, + IN WIRELESS_MODE WirelessMode, + IN u4Byte ratr_bitmap, + IN u1Byte rssi_level +); + +VOID +ODM_UpdateInitRate( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Rate + ); + +VOID +ODM_InitializeTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer, + IN RT_TIMER_CALL_BACK CallBackFunc, + IN PVOID pContext, + IN const char* szID +); + +VOID +ODM_CancelAllTimers( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_ReleaseAllTimers( + IN PDM_ODM_T pDM_Odm +); + +//Remove ODM_DynamicARFBSelect() by RS_James + +PVOID +PhyDM_Get_Structure( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Structure_Type +); + + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +void odm_dtc(PDM_ODM_T pDM_Odm); +#endif /* #if (DM_ODM_SUPPORT_TYPE == ODM_CE) */ + +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_ACS.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_ACS.c new file mode 100755 index 000000000000..f82846d71e6c --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_ACS.c @@ -0,0 +1,213 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + + +u1Byte +ODM_GetAutoChannelSelectResult( + IN PVOID pDM_VOID, + IN u1Byte Band +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PACS pACS = &pDM_Odm->DM_ACS; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(Band == ODM_BAND_2_4G) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[ACS] ODM_GetAutoChannelSelectResult(): CleanChannel_2G(%d)\n", pACS->CleanChannel_2G)); + return (u1Byte)pACS->CleanChannel_2G; + } + else + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[ACS] ODM_GetAutoChannelSelectResult(): CleanChannel_5G(%d)\n", pACS->CleanChannel_5G)); + return (u1Byte)pACS->CleanChannel_5G; + } +#else + return (u1Byte)pACS->CleanChannel_2G; +#endif + +} + +VOID +odm_AutoChannelSelectSetting( + IN PVOID pDM_VOID, + IN BOOLEAN IsEnable +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte period = 0x2710;// 40ms in default + u2Byte NHMType = 0x7; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSetting()=========> \n")); + + if(IsEnable) + {//20 ms + period = 0x1388; + NHMType = 0x1; + } + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + //PHY parameters initialize for ac series + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11AC+2, period); //0x990[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms + //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT8|BIT9|BIT10, NHMType); //0x994[9:8]=3 enable CCX + } + else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + //PHY parameters initialize for n series + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N+2, period); //0x894[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms + //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, NHMType); //0x890[9:8]=3 enable CCX + } +#endif +} + +VOID +odm_AutoChannelSelectInit( + IN PVOID pDM_VOID +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PACS pACS = &pDM_Odm->DM_ACS; + u1Byte i; + + if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT)) + return; + + if(pACS->bForceACSResult) + return; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectInit()=========> \n")); + + pACS->CleanChannel_2G = 1; + pACS->CleanChannel_5G = 36; + + for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i) + { + pACS->Channel_Info_2G[0][i] = 0; + pACS->Channel_Info_2G[1][i] = 0; + } + + if(pDM_Odm->SupportICType & (ODM_IC_11AC_SERIES|ODM_RTL8192D)) + { + for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i) + { + pACS->Channel_Info_5G[0][i] = 0; + pACS->Channel_Info_5G[1][i] = 0; + } + } +#endif +} + +VOID +odm_AutoChannelSelectReset( + IN PVOID pDM_VOID +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PACS pACS = &pDM_Odm->DM_ACS; + + if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT)) + return; + + if(pACS->bForceACSResult) + return; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectReset()=========> \n")); + + odm_AutoChannelSelectSetting(pDM_Odm,TRUE);// for 20ms measurement + Phydm_NHMCounterStatisticsReset(pDM_Odm); +#endif +} + +VOID +odm_AutoChannelSelect( + IN PVOID pDM_VOID, + IN u1Byte Channel +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PACS pACS = &pDM_Odm->DM_ACS; + u1Byte ChannelIDX = 0, SearchIDX = 0; + u2Byte MaxScore=0; + + if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Return: SupportAbility ODM_BB_NHM_CNT is disabled\n")); + return; + } + + if(pACS->bForceACSResult) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Force 2G clean channel = %d, 5G clean channel = %d\n", + pACS->CleanChannel_2G, pACS->CleanChannel_5G)); + return; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Channel = %d=========> \n", Channel)); + + Phydm_GetNHMCounterStatistics(pDM_Odm); + odm_AutoChannelSelectSetting(pDM_Odm,FALSE); + + if(Channel >=1 && Channel <=14) + { + ChannelIDX = Channel - 1; + pACS->Channel_Info_2G[1][ChannelIDX]++; + + if(pACS->Channel_Info_2G[1][ChannelIDX] >= 2) + pACS->Channel_Info_2G[0][ChannelIDX] = (pACS->Channel_Info_2G[0][ChannelIDX] >> 1) + + (pACS->Channel_Info_2G[0][ChannelIDX] >> 2) + (pDM_Odm->NHM_cnt_0>>2); + else + pACS->Channel_Info_2G[0][ChannelIDX] = pDM_Odm->NHM_cnt_0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): NHM_cnt_0 = %d \n", pDM_Odm->NHM_cnt_0)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Channel_Info[0][%d] = %d, Channel_Info[1][%d] = %d\n", ChannelIDX, pACS->Channel_Info_2G[0][ChannelIDX], ChannelIDX, pACS->Channel_Info_2G[1][ChannelIDX])); + + for(SearchIDX = 0; SearchIDX < ODM_MAX_CHANNEL_2G; SearchIDX++) + { + if(pACS->Channel_Info_2G[1][SearchIDX] != 0) + { + if(pACS->Channel_Info_2G[0][SearchIDX] >= MaxScore) + { + MaxScore = pACS->Channel_Info_2G[0][SearchIDX]; + pACS->CleanChannel_2G = SearchIDX+1; + } + } + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("(1)odm_AutoChannelSelect(): 2G: CleanChannel_2G = %d, MaxScore = %d \n", + pACS->CleanChannel_2G, MaxScore)); + + } + else if(Channel >= 36) + { + // Need to do + pACS->CleanChannel_5G = Channel; + } +#endif +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_ACS.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_ACS.h new file mode 100755 index 000000000000..d24c4c63bbde --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_ACS.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMACS_H__ +#define __PHYDMACS_H__ + +#define ACS_VERSION "1.0" + +#define ODM_MAX_CHANNEL_2G 14 +#define ODM_MAX_CHANNEL_5G 24 + +typedef struct _ACS_ +{ + BOOLEAN bForceACSResult; + u1Byte CleanChannel_2G; + u1Byte CleanChannel_5G; + u2Byte Channel_Info_2G[2][ODM_MAX_CHANNEL_2G]; //Channel_Info[1]: Channel Score, Channel_Info[2]:Channel_Scan_Times + u2Byte Channel_Info_5G[2][ODM_MAX_CHANNEL_5G]; +}ACS, *PACS; + + +VOID +odm_AutoChannelSelectInit( + IN PVOID pDM_VOID +); + +VOID +odm_AutoChannelSelectReset( + IN PVOID pDM_VOID +); + +VOID +odm_AutoChannelSelect( + IN PVOID pDM_VOID, + IN u1Byte Channel +); + +u1Byte +ODM_GetAutoChannelSelectResult( + IN PVOID pDM_VOID, + IN u1Byte Band +); + +#endif \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDect.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDect.c new file mode 100755 index 000000000000..d6a1c5d86faf --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDect.c @@ -0,0 +1,1206 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ + +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN |ODM_CE)) + +//IS_ANT_DETECT_SUPPORT_SINGLE_TONE(Adapter) +//IS_ANT_DETECT_SUPPORT_RSSI(Adapter) +//IS_ANT_DETECT_SUPPORT_PSD(Adapter) + +//1 [1. Single Tone Method] =================================================== + + +VOID +odm_PHY_SaveAFERegisters( + IN PDM_ODM_T pDM_Odm, + IN pu4Byte AFEReg, + IN pu4Byte AFEBackup, + IN u4Byte RegisterNum + ) +{ + u4Byte i; + + //RT_DISP(FINIT, INIT_IQK, ("Save ADDA parameters.\n")); + for( i = 0 ; i < RegisterNum ; i++){ + AFEBackup[i] = ODM_GetBBReg(pDM_Odm, AFEReg[i], bMaskDWord); + } +} + +VOID +odm_PHY_ReloadAFERegisters( + IN PDM_ODM_T pDM_Odm, + IN pu4Byte AFEReg, + IN pu4Byte AFEBackup, + IN u4Byte RegiesterNum + ) +{ + u4Byte i; + + //RT_DISP(FINIT, INIT_IQK, ("Reload ADDA power saving parameters !\n")); + for(i = 0 ; i < RegiesterNum; i++) + { + + ODM_SetBBReg(pDM_Odm, AFEReg[i], bMaskDWord, AFEBackup[i]); + } +} + +// +// Description: +// Set Single/Dual Antenna default setting for products that do not do detection in advance. +// +// Added by Joseph, 2012.03.22 +// +VOID +ODM_SingleDualAntennaDefaultSetting( + IN PDM_ODM_T pDM_Odm + ) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + PADAPTER pAdapter = pDM_Odm->Adapter; + + u1Byte btAntNum=BT_GetPgAntNum(pAdapter); + // Set default antenna A and B status + if(btAntNum == 2) + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=TRUE; + + } + else if(btAntNum == 1) + {// Set antenna A as default + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=FALSE; + + } + else + { + RT_ASSERT(FALSE, ("Incorrect antenna number!!\n")); + } +} + + +//2 8723A ANT DETECT +// +// Description: +// Implement IQK single tone for RF DPK loopback and BB PSD scanning. +// This function is cooperated with BB team Neil. +// +// Added by Roger, 2011.12.15 +// +BOOLEAN +ODM_SingleDualAntennaDetection( + IN PDM_ODM_T pDM_Odm, + IN u1Byte mode + ) +{ + PADAPTER pAdapter = pDM_Odm->Adapter; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + u4Byte CurrentChannel,RfLoopReg; + u1Byte n; + u4Byte Reg88c, Regc08, Reg874, Regc50, Reg948, Regb2c, Reg92c, Reg930, Reg064, AFE_rRx_Wait_CCA; + u1Byte initial_gain = 0x5a; + u4Byte PSD_report_tmp; + u4Byte AntA_report = 0x0, AntB_report = 0x0,AntO_report=0x0,temp; + BOOLEAN bResult = TRUE; + u4Byte AFE_Backup[16]; + u4Byte AFE_REG_8723A[16] = { + rRx_Wait_CCA, rTx_CCK_RFON, + rTx_CCK_BBON, rTx_OFDM_RFON, + rTx_OFDM_BBON, rTx_To_Rx, + rTx_To_Tx, rRx_CCK, + rRx_OFDM, rRx_Wait_RIFS, + rRx_TO_Rx, rStandby, + rSleep, rPMPD_ANAEN, + rFPGA0_XCD_SwitchControl, rBlue_Tooth}; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection()============> \n")); + + + if(!(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C|ODM_RTL8723B))) + return bResult; + + // Retrieve antenna detection registry info, added by Roger, 2012.11.27. + if(!IS_ANT_DETECT_SUPPORT_SINGLE_TONE(pAdapter)) + return bResult; + + if(pDM_Odm->SupportICType == ODM_RTL8192C) + { + //Which path in ADC/DAC is turnned on for PSD: both I/Q + ODM_SetBBReg(pDM_Odm, 0x808, BIT10|BIT11, 0x3); + //Ageraged number: 8 + ODM_SetBBReg(pDM_Odm, 0x808, BIT12|BIT13, 0x1); + //pts = 128; + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x0); + } + + //1 Backup Current RF/BB Settings + + CurrentChannel = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask); + RfLoopReg = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x00, bRFRegOffsetMask); + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); // change to Antenna A + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + Reg92c = ODM_GetBBReg(pDM_Odm, rDPDT_control, bMaskDWord); + Reg930 = ODM_GetBBReg(pDM_Odm, rfe_ctrl_anta_src, bMaskDWord); + Reg948 = ODM_GetBBReg(pDM_Odm, rS0S1_PathSwitch, bMaskDWord); + Regb2c = ODM_GetBBReg(pDM_Odm, rAGC_table_select, bMaskDWord); + Reg064 = ODM_GetMACReg(pDM_Odm, rSYM_WLBT_PAPE_SEL, BIT29); + ODM_SetBBReg(pDM_Odm, rDPDT_control, 0x3, 0x1); + ODM_SetBBReg(pDM_Odm, rfe_ctrl_anta_src, 0xff, 0x77); + ODM_SetMACReg(pDM_Odm, rSYM_WLBT_PAPE_SEL, BIT29, 0x1); //dbg 7 + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, 0x3c0, 0x0);//dbg 8 + ODM_SetBBReg(pDM_Odm, rAGC_table_select, BIT31, 0x0); + } + + ODM_StallExecution(10); + + //Store A Path Register 88c, c08, 874, c50 + Reg88c = ODM_GetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord); + Regc08 = ODM_GetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord); + Reg874 = ODM_GetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord); + Regc50 = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord); + + // Store AFE Registers + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + AFE_rRx_Wait_CCA = ODM_GetBBReg(pDM_Odm, rRx_Wait_CCA,bMaskDWord); + + //Set PSD 128 pts + ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT14|BIT15, 0x0); //128 pts + + // To SET CH1 to do + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x7401); //Channel 1 + + // AFE all on step + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + { + ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_CCK_RFON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_CCK_BBON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_OFDM_RFON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_OFDM_BBON, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_To_Rx, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rTx_To_Tx, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_CCK, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_OFDM, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_Wait_RIFS, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rRx_TO_Rx, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rStandby, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rSleep, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rPMPD_ANAEN, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_SwitchControl, bMaskDWord, 0x6FDB25A4); + ODM_SetBBReg(pDM_Odm, rBlue_Tooth, bMaskDWord, 0x6FDB25A4); + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x01c00016); + } + + // 3 wire Disable + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, 0xCCF000C0); + + //BB IQK Setting + ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800E4); + ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22208000); + + //IQK setting tone@ 4.34Mhz + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008C1C); + ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); + + //Page B init + ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00080000); + ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x0f600000); + ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + { + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82150008); + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28150008); + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82150016); + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28150016); + } + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x001028d0); + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7f, initial_gain); + + //RF loop Setting + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x0, 0xFFFFF, 0x50008); + + //IQK Single tone start + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x808000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + ODM_StallExecution(10000); + + // PSD report of antenna A + PSD_report_tmp=0x0; + for (n=0;n<2;n++) + { + PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); + if(PSD_report_tmp >AntA_report) + AntA_report=PSD_report_tmp; + } + + // change to Antenna B + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_B); + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + //ODM_SetBBReg(pDM_Odm, rDPDT_control, 0x3, 0x2); + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, 0xfff, 0x280); + ODM_SetBBReg(pDM_Odm, rAGC_table_select, BIT31, 0x1); + } + + ODM_StallExecution(10); + + // PSD report of antenna B + PSD_report_tmp=0x0; + for (n=0;n<2;n++) + { + PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); + if(PSD_report_tmp > AntB_report) + AntB_report=PSD_report_tmp; + } + + // change to open case + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + { + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, 0); // change to Antenna A + + ODM_StallExecution(10); + + // PSD report of open case + PSD_report_tmp=0x0; + for (n=0;n<2;n++) + { + PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); + if(PSD_report_tmp > AntO_report) + AntO_report=PSD_report_tmp; + } + } + //Close IQK Single Tone function + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000); + + //1 Return to antanna A + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); // change to Antenna A + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + // external DPDT + ODM_SetBBReg(pDM_Odm, rDPDT_control, bMaskDWord, Reg92c); + + //internal S0/S1 + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, bMaskDWord, Reg948); + ODM_SetBBReg(pDM_Odm, rAGC_table_select, bMaskDWord, Regb2c); + ODM_SetBBReg(pDM_Odm, rfe_ctrl_anta_src, bMaskDWord, Reg930); + ODM_SetMACReg(pDM_Odm, rSYM_WLBT_PAPE_SEL, BIT29, Reg064); + } + + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, Reg88c); + ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, Regc08); + ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, Reg874); + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord, Regc50); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,CurrentChannel); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x00, bRFRegOffsetMask,RfLoopReg); + + //Reload AFE Registers + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8192C)) + odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, AFE_rRx_Wait_CCA); + + if(pDM_Odm->SupportICType == ODM_RTL8723A) + { + //2 Test Ant B based on Ant A is ON + if(mode==ANTTESTB) + { + if(AntA_report >= 100) + { + if(AntB_report > (AntA_report+1)) + { + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n")); + } + else + { + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Dual Antenna is A and B\n")); + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + pDM_SWAT_Table->ANTB_ON=FALSE; // Set Antenna B off as default + bResult = FALSE; + } + } + //2 Test Ant A and B based on DPDT Open + else if(mode==ANTTESTALL) + { + if((AntO_report >=100) && (AntO_report <=118)) + { + if(AntA_report > (AntO_report+1)) + { + pDM_SWAT_Table->ANTA_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant A is OFF\n")); + } + else + { + pDM_SWAT_Table->ANTA_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant A is ON\n")); + } + + if(AntB_report > (AntO_report+2)) + { + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant B is OFF\n")); + } + else + { + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Ant B is ON\n")); + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_A[%d]= %d \n", 2416, AntA_report)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_B[%d]= %d \n", 2416, AntB_report)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_O[%d]= %d \n", 2416, AntO_report)); + + pDM_Odm->AntDetectedInfo.bAntDetected= TRUE; + pDM_Odm->AntDetectedInfo.dBForAntA = AntA_report; + pDM_Odm->AntDetectedInfo.dBForAntB = AntB_report; + pDM_Odm->AntDetectedInfo.dBForAntO = AntO_report; + + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("return FALSE!!\n")); + bResult = FALSE; + } + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8192C) + { + if(AntA_report >= 100) + { + if(AntB_report > (AntA_report+2)) + { + pDM_SWAT_Table->ANTA_ON=FALSE; + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna B\n")); + } + else if(AntA_report > (AntB_report+2)) + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n")); + } + else + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=TRUE; + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + pDM_SWAT_Table->ANTA_ON=TRUE; // Set Antenna A on as default + pDM_SWAT_Table->ANTB_ON=FALSE; // Set Antenna B off as default + bResult = FALSE; + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_A[%d]= %d \n", 2416, AntA_report)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_B[%d]= %d \n", 2416, AntB_report)); + + //2 Test Ant B based on Ant A is ON + if((AntA_report >= 100) && (AntB_report >= 100) && (AntA_report <= 135) && (AntB_report <= 135)) + { + u1Byte TH1=2, TH2=6; + + if((AntA_report - AntB_report < TH1) || (AntB_report - AntA_report < TH1)) + { + pDM_SWAT_Table->ANTA_ON=TRUE; + pDM_SWAT_Table->ANTB_ON=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ODM_SingleDualAntennaDetection(): Dual Antenna\n")); + } + else if(((AntA_report - AntB_report >= TH1) && (AntA_report - AntB_report <= TH2)) || + ((AntB_report - AntA_report >= TH1) && (AntB_report - AntA_report <= TH2))) + { + pDM_SWAT_Table->ANTA_ON=FALSE; + pDM_SWAT_Table->ANTB_ON=FALSE; + bResult = FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + } + else + { + pDM_SWAT_Table->ANTA_ON = TRUE; + pDM_SWAT_Table->ANTB_ON=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ODM_SingleDualAntennaDetection(): Single Antenna\n")); + } + pDM_Odm->AntDetectedInfo.bAntDetected= TRUE; + pDM_Odm->AntDetectedInfo.dBForAntA = AntA_report; + pDM_Odm->AntDetectedInfo.dBForAntB = AntB_report; + pDM_Odm->AntDetectedInfo.dBForAntO = AntO_report; + + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("return FALSE!!\n")); + bResult = FALSE; + } + } + return bResult; + +} + + + +//1 [2. Scan AP RSSI Method] ================================================== + + +void +odm_SwAntDetectInit( + IN PDM_ODM_T pDM_Odm + ) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + + //pDM_SWAT_Table->SWAS_NoLink_BK_Reg92c = ODM_Read4Byte(pDM_Odm, rDPDT_control); + //pDM_SWAT_Table->PreAntenna = MAIN_ANT; + //pDM_SWAT_Table->CurAntenna = MAIN_ANT; + pDM_SWAT_Table->SWAS_NoLink_State = 0; + pDM_SWAT_Table->Pre_Aux_FailDetec = FALSE; + pDM_SWAT_Table->SWAS_NoLink_BK_Reg948 = 0xff; +} + + +BOOLEAN +ODM_SwAntDivCheckBeforeLink( + IN PDM_ODM_T pDM_Odm + ) +{ + +#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM) + + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE* pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + s1Byte Score = 0; + PRT_WLAN_BSS pTmpBssDesc, pTestBssDesc; + u1Byte power_target = 10, power_target_L = 9, power_target_H = 16; + u1Byte tmp_power_diff = 0,power_diff = 0,avg_power_diff = 0,max_power_diff = 0,min_power_diff = 0xff; + u2Byte index, counter = 0; + static u1Byte ScanChannel; + u8Byte tStamp_diff = 0; + u4Byte tmp_SWAS_NoLink_BK_Reg948; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ANTA_ON = (( %d )) , ANTB_ON = (( %d )) \n",pDM_Odm->DM_SWAT_Table.ANTA_ON ,pDM_Odm->DM_SWAT_Table.ANTB_ON )); + + //if(HP id) + { + if(pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult==TRUE && pDM_Odm->SupportICType == ODM_RTL8723B) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("8723B RSSI-based Antenna Detection is done\n")); + return FALSE; + } + + if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + if(pDM_SWAT_Table->SWAS_NoLink_BK_Reg948 == 0xff) + pDM_SWAT_Table->SWAS_NoLink_BK_Reg948 = ODM_Read4Byte(pDM_Odm, rS0S1_PathSwitch ); + } + } + + if (pDM_Odm->Adapter == NULL) //For BSOD when plug/unplug fast. //By YJ,120413 + { // The ODM structure is not initialized. + return FALSE; + } + + // Retrieve antenna detection registry info, added by Roger, 2012.11.27. + if(!IS_ANT_DETECT_SUPPORT_RSSI(Adapter)) + { + return FALSE; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Antenna Detection: RSSI Method\n")); + } + + // Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF. + PlatformAcquireSpinLock(Adapter, RT_RF_STATE_SPINLOCK); + if(pHalData->eRFPowerState!=eRfOn || pMgntInfo->RFChangeInProgress || pMgntInfo->bMediaConnect) + { + PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink(): RFChangeInProgress(%x), eRFPowerState(%x)\n", + pMgntInfo->RFChangeInProgress, pHalData->eRFPowerState)); + + pDM_SWAT_Table->SWAS_NoLink_State = 0; + + return FALSE; + } + else + { + PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("pDM_SWAT_Table->SWAS_NoLink_State = %d\n", pDM_SWAT_Table->SWAS_NoLink_State)); + //1 Run AntDiv mechanism "Before Link" part. + if(pDM_SWAT_Table->SWAS_NoLink_State == 0) + { + //1 Prepare to do Scan again to check current antenna state. + + // Set check state to next step. + pDM_SWAT_Table->SWAS_NoLink_State = 1; + + // Copy Current Scan list. + pMgntInfo->tmpNumBssDesc = pMgntInfo->NumBssDesc; + PlatformMoveMemory((PVOID)Adapter->MgntInfo.tmpbssDesc, (PVOID)pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC); + + // Go back to scan function again. + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Scan one more time\n")); + pMgntInfo->ScanStep=0; + pMgntInfo->bScanAntDetect = TRUE; + ScanChannel = odm_SwAntDivSelectScanChnl(Adapter); + + + if(pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8821)) + { + if(pDM_FatTable->RxIdleAnt == MAIN_ANT) + ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT); + else + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + if(ScanChannel == 0) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink(): No AP List Avaiable, Using Ant(%s)\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"AUX_ANT":"MAIN_ANT")); + + if(IS_5G_WIRELESS_MODE(pMgntInfo->dot11CurrentWirelessMode)) + { + pDM_SWAT_Table->Ant5G = pDM_FatTable->RxIdleAnt; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant5G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + } + else + { + pDM_SWAT_Table->Ant2G = pDM_FatTable->RxIdleAnt; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant2G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + } + return FALSE; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink: Change to %s for testing.\n", ((pDM_FatTable->RxIdleAnt == MAIN_ANT)?"MAIN_ANT":"AUX_ANT"))); + } + else if(pDM_Odm->SupportICType & (ODM_RTL8192C|ODM_RTL8723B)) + { + if(pDM_Odm->SupportICType == ODM_RTL8192C) + { + // Switch Antenna to another one. + pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna; + pDM_SWAT_Table->CurAntenna = (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?AUX_ANT:MAIN_ANT; + + pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 = ((pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 & 0xfffffcff) | (pDM_SWAT_Table->CurAntenna<<8)); + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, bMaskDWord, pDM_SWAT_Table->SWAS_NoLink_BK_Reg860); + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + // Switch Antenna to another one. + + tmp_SWAS_NoLink_BK_Reg948 = ODM_Read4Byte(pDM_Odm, rS0S1_PathSwitch ); + + if( (pDM_SWAT_Table->CurAntenna = MAIN_ANT) && (tmp_SWAS_NoLink_BK_Reg948==0x200)) + { + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, 0xfff, 0x280); + ODM_SetBBReg(pDM_Odm, rAGC_table_select, BIT31, 0x1); + pDM_SWAT_Table->CurAntenna = AUX_ANT; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Reg[948]= (( %x )) was in wrong state\n", tmp_SWAS_NoLink_BK_Reg948 )); + return FALSE; + } + ODM_StallExecution(10); + + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Change to (( %s-ant)) for testing.\n", (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?"MAIN":"AUX")); + } + + odm_SwAntDivConstructScanChnl(Adapter, ScanChannel); + PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5); + + return TRUE; + } + else //pDM_SWAT_Table->SWAS_NoLink_State == 1 + { + //1 ScanComple() is called after antenna swiched. + //1 Check scan result and determine which antenna is going + //1 to be used. + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" tmpNumBssDesc= (( %d )) \n",pMgntInfo->tmpNumBssDesc));// debug for Dino + + for(index = 0; index < pMgntInfo->tmpNumBssDesc; index++) + { + pTmpBssDesc = &(pMgntInfo->tmpbssDesc[index]); // Antenna 1 + pTestBssDesc = &(pMgntInfo->bssDesc[index]); // Antenna 2 + + if(PlatformCompareMemory(pTestBssDesc->bdBssIdBuf, pTmpBssDesc->bdBssIdBuf, 6)!=0) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): ERROR!! This shall not happen.\n")); + continue; + } + + if(pDM_Odm->SupportICType != ODM_RTL8723B) + { + if(pTmpBssDesc->ChannelNumber == ScanChannel) + { + if(pTmpBssDesc->RecvSignalPower > pTestBssDesc->RecvSignalPower) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Compare scan entry: Score++\n")); + RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", pTmpBssDesc->bdSsIdBuf, pTmpBssDesc->bdSsIdLen); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n\n", pTmpBssDesc->ChannelNumber, pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + + Score++; + PlatformMoveMemory(pTestBssDesc, pTmpBssDesc, sizeof(RT_WLAN_BSS)); + } + else if(pTmpBssDesc->RecvSignalPower < pTestBssDesc->RecvSignalPower) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Compare scan entry: Score--\n")); + RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", pTmpBssDesc->bdSsIdBuf, pTmpBssDesc->bdSsIdLen); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n\n", pTmpBssDesc->ChannelNumber, pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + Score--; + } + else + { + if(pTestBssDesc->bdTstamp - pTmpBssDesc->bdTstamp < 5000) + { + RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", pTmpBssDesc->bdSsIdBuf, pTmpBssDesc->bdSsIdLen); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n", pTmpBssDesc->ChannelNumber, pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("The 2nd Antenna didn't get this AP\n\n")); + } + } + } + } + else // 8723B + { + if(pTmpBssDesc->ChannelNumber == ScanChannel) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ChannelNumber == ScanChannel -> (( %d )) \n", pTmpBssDesc->ChannelNumber )); + + if(pTmpBssDesc->RecvSignalPower > pTestBssDesc->RecvSignalPower) // Pow(Ant1) > Pow(Ant2) + { + counter++; + tmp_power_diff=(u1Byte)(pTmpBssDesc->RecvSignalPower - pTestBssDesc->RecvSignalPower); + power_diff = power_diff + tmp_power_diff; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), pTmpBssDesc->bdSsIdBuf); + ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), pTmpBssDesc->bdBssIdBuf); + + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("tmp_power_diff: (( %d)),max_power_diff: (( %d)),min_power_diff: (( %d)) \n", tmp_power_diff,max_power_diff,min_power_diff)); + if(tmp_power_diff > max_power_diff) + max_power_diff=tmp_power_diff; + if(tmp_power_diff < min_power_diff) + min_power_diff=tmp_power_diff; + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("max_power_diff: (( %d)),min_power_diff: (( %d)) \n",max_power_diff,min_power_diff)); + + PlatformMoveMemory(pTestBssDesc, pTmpBssDesc, sizeof(RT_WLAN_BSS)); + } + else if(pTestBssDesc->RecvSignalPower > pTmpBssDesc->RecvSignalPower) // Pow(Ant1) < Pow(Ant2) + { + counter++; + tmp_power_diff=(u1Byte)(pTestBssDesc->RecvSignalPower - pTmpBssDesc->RecvSignalPower); + power_diff = power_diff + tmp_power_diff; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), pTmpBssDesc->bdSsIdBuf); + ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), pTmpBssDesc->bdBssIdBuf); + if(tmp_power_diff > max_power_diff) + max_power_diff=tmp_power_diff; + if(tmp_power_diff < min_power_diff) + min_power_diff=tmp_power_diff; + } + else // Pow(Ant1) = Pow(Ant2) + { + if(pTestBssDesc->bdTstamp > pTmpBssDesc->bdTstamp) // Stamp(Ant1) < Stamp(Ant2) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("time_diff: %lld\n", (pTestBssDesc->bdTstamp-pTmpBssDesc->bdTstamp)/1000)); + if(pTestBssDesc->bdTstamp - pTmpBssDesc->bdTstamp > 5000) + { + counter++; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), pTmpBssDesc->bdSsIdBuf); + ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), pTmpBssDesc->bdBssIdBuf); + min_power_diff = 0; + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Error !!!]: Time_diff: %lld\n", (pTestBssDesc->bdTstamp-pTmpBssDesc->bdTstamp)/1000)); + } + } + } + } + } + + if(pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8821)) + { + if(pMgntInfo->NumBssDesc!=0 && Score<0) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink(): Using Ant(%s)\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink(): Remain Ant(%s)\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"AUX_ANT":"MAIN_ANT")); + + if(pDM_FatTable->RxIdleAnt == MAIN_ANT) + ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT); + else + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + } + + if(IS_5G_WIRELESS_MODE(pMgntInfo->dot11CurrentWirelessMode)) + { + pDM_SWAT_Table->Ant5G = pDM_FatTable->RxIdleAnt; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant5G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + } + else + { + pDM_SWAT_Table->Ant2G = pDM_FatTable->RxIdleAnt; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant2G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + if(counter == 0) + { + if(pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec == FALSE) + { + pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec = TRUE; + pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Counter=(( 0 )) , [[ Cannot find any AP with Aux-ant ]] -> Scan Target-channel again \n")); + + //3 [ Scan again ] + odm_SwAntDivConstructScanChnl(Adapter, ScanChannel); + PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5); + return TRUE; + } + else// Pre_Aux_FailDetec == TRUE + { + //2 [ Single Antenna ] + pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec = FALSE; + pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Counter=(( 0 )) , [[ Still cannot find any AP ]] \n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): Single antenna\n")); + } + pDM_Odm->DM_SWAT_Table.Aux_FailDetec_Counter++; + } + else + { + pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec = FALSE; + + if(counter==3) + { + avg_power_diff = ((power_diff-max_power_diff - min_power_diff)>>1)+ ((max_power_diff + min_power_diff)>>2); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter: (( %d )) , power_diff: (( %d )) \n", counter, power_diff)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ counter==3 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) , min_power_diff: (( %d )) \n", avg_power_diff,max_power_diff, min_power_diff)); + } + else if(counter>=4) + { + avg_power_diff=(power_diff-max_power_diff - min_power_diff) / (counter - 2); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter: (( %d )) , power_diff: (( %d )) \n", counter, power_diff)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ counter>=4 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) , min_power_diff: (( %d )) \n", avg_power_diff,max_power_diff, min_power_diff)); + + } + else//counter==1,2 + { + avg_power_diff=power_diff/counter; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("avg_power_diff: (( %d )) , counter: (( %d )) , power_diff: (( %d )) \n", avg_power_diff,counter, power_diff)); + } + + //2 [ Retry ] + if( (avg_power_diff >=power_target_L) && (avg_power_diff <=power_target_H) ) + { + pDM_Odm->DM_SWAT_Table.Retry_Counter++; + + if(pDM_Odm->DM_SWAT_Table.Retry_Counter<=3) + { + pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[[ Low confidence result ]] avg_power_diff= (( %d )) -> Scan Target-channel again ]] \n", avg_power_diff)); + + //3 [ Scan again ] + odm_SwAntDivConstructScanChnl(Adapter, ScanChannel); + PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5); + return TRUE; + } + else + { + pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[[ Still Low confidence result ]] (( Retry_Counter > 3 )) \n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): Single antenna\n")); + } + + } + //2 [ Dual Antenna ] + else if( (pMgntInfo->NumBssDesc != 0) && (avg_power_diff < power_target_L) ) + { + pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE; + if(pDM_Odm->DM_SWAT_Table.ANTB_ON == FALSE) + { + pDM_Odm->DM_SWAT_Table.ANTA_ON = TRUE; + pDM_Odm->DM_SWAT_Table.ANTB_ON = TRUE; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ODM_SwAntDivCheckBeforeLink(): Dual antenna\n")); + pDM_Odm->DM_SWAT_Table.Dual_Ant_Counter++; + + // set bt coexDM from 1ant coexDM to 2ant coexDM + BT_SetBtCoexAntNum(Adapter, BT_COEX_ANT_TYPE_DETECTED, 2); + + //3 [ Init antenna diversity ] + pDM_Odm->SupportAbility |= ODM_BB_ANT_DIV; + ODM_AntDivInit(pDM_Odm); + } + //2 [ Single Antenna ] + else if(avg_power_diff > power_target_H) + { + pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE; + if(pDM_Odm->DM_SWAT_Table.ANTB_ON == TRUE) + { + pDM_Odm->DM_SWAT_Table.ANTA_ON = TRUE; + pDM_Odm->DM_SWAT_Table.ANTB_ON = FALSE; + //BT_SetBtCoexAntNum(Adapter, BT_COEX_ANT_TYPE_DETECTED, 1); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): Single antenna\n")); + pDM_Odm->DM_SWAT_Table.Single_Ant_Counter++; + } + } + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("bResult=(( %d ))\n",pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Dual_Ant_Counter = (( %d )), Single_Ant_Counter = (( %d )) , Retry_Counter = (( %d )) , Aux_FailDetec_Counter = (( %d ))\n\n\n", + pDM_Odm->DM_SWAT_Table.Dual_Ant_Counter,pDM_Odm->DM_SWAT_Table.Single_Ant_Counter,pDM_Odm->DM_SWAT_Table.Retry_Counter,pDM_Odm->DM_SWAT_Table.Aux_FailDetec_Counter)); + + //2 recover the antenna setting + + if(pDM_Odm->DM_SWAT_Table.ANTB_ON == FALSE) + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, 0xfff, (pDM_SWAT_Table->SWAS_NoLink_BK_Reg948)); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("bResult=(( %d )), Recover Reg[948]= (( %x )) \n\n",pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult, pDM_SWAT_Table->SWAS_NoLink_BK_Reg948 )); + + + } + else if(pDM_Odm->SupportICType == ODM_RTL8192C) + { + if(pMgntInfo->NumBssDesc!=0 && Score<=0) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink(): Using Ant(%s)\n", (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?"MAIN":"AUX")); + + pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink(): Remain Ant(%s)\n", (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?"AUX":"MAIN")); + + pDM_SWAT_Table->CurAntenna = pDM_SWAT_Table->PreAntenna; + + //PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, DM_SWAT_Table.CurAntenna); + pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 = ((pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 & 0xfffffcff) | (pDM_SWAT_Table->CurAntenna<<8)); + PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, pDM_SWAT_Table->SWAS_NoLink_BK_Reg860); + } + } + + // Check state reset to default and wait for next time. + pDM_SWAT_Table->SWAS_NoLink_State = 0; + pMgntInfo->bScanAntDetect = FALSE; + + return FALSE; + } + +#else + return FALSE; +#endif + +return FALSE; +} + + + + + + +//1 [3. PSD Method] ========================================================== + + + + +u4Byte +odm_GetPSDData( + IN PDM_ODM_T pDM_Odm, + IN u2Byte point, + IN u1Byte initial_gain) +{ + u4Byte psd_report; + + ODM_SetBBReg(pDM_Odm, 0x808, 0x3FF, point); + ODM_SetBBReg(pDM_Odm, 0x808, BIT22, 1); //Start PSD calculation, Reg808[22]=0->1 + ODM_StallExecution(150);//Wait for HW PSD report + ODM_SetBBReg(pDM_Odm, 0x808, BIT22, 0);//Stop PSD calculation, Reg808[22]=1->0 + psd_report = ODM_GetBBReg(pDM_Odm,0x8B4, bMaskDWord) & 0x0000FFFF;//Read PSD report, Reg8B4[15:0] + + psd_report = (u4Byte) (ConvertTo_dB(psd_report));//+(u4Byte)(initial_gain); + return psd_report; +} + + + +VOID +ODM_SingleDualAntennaDetection_PSD( + IN PDM_ODM_T pDM_Odm +) +{ + PADAPTER pAdapter = pDM_Odm->Adapter; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + u4Byte Channel_ori; + u1Byte initial_gain = 0x36; + u1Byte tone_idx; + u1Byte Tone_lenth_1=7, Tone_lenth_2=4; + u2Byte Tone_idx_1[7]={88, 104, 120, 8, 24, 40, 56}; + u2Byte Tone_idx_2[4]={8, 24, 40, 56}; + u4Byte PSD_report_Main[11]={0}, PSD_report_Aux[11]={0}; + //u1Byte Tone_lenth_1=4, Tone_lenth_2=2; + //u2Byte Tone_idx_1[4]={88, 120, 24, 56}; + //u2Byte Tone_idx_2[2]={ 24, 56}; + //u4Byte PSD_report_Main[6]={0}, PSD_report_Aux[6]={0}; + + u4Byte PSD_report_temp,MAX_PSD_report_Main=0,MAX_PSD_report_Aux=0; + u4Byte PSD_power_threshold; + u4Byte Main_psd_result=0, Aux_psd_result=0; + u4Byte Regc50, Reg948, Regb2c,Regc14,Reg908; + u4Byte i=0,test_num=8; + + + if(pDM_Odm->SupportICType != ODM_RTL8723B) + return; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection_PSD()============> \n")); + + //2 [ Backup Current RF/BB Settings ] + + Channel_ori = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask); + Reg948 = ODM_GetBBReg(pDM_Odm, rS0S1_PathSwitch, bMaskDWord); + Regb2c = ODM_GetBBReg(pDM_Odm, rAGC_table_select, bMaskDWord); + Regc50 = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord); + Regc14 = ODM_GetBBReg(pDM_Odm, 0xc14, bMaskDWord); + Reg908 = ODM_GetBBReg(pDM_Odm, 0x908, bMaskDWord); + + //2 [ Setting for doing PSD function (CH4)] + ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 0); //disable whole CCK block + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0xFF); // Turn off TX -> Pause TX Queue + ODM_SetBBReg(pDM_Odm, 0xC14, bMaskDWord, 0x0); // [ Set IQK Matrix = 0 ] equivalent to [ Turn off CCA] + + // PHYTXON while loop + ODM_SetBBReg(pDM_Odm, 0x908, bMaskDWord, 0x803); + while (ODM_GetBBReg(pDM_Odm, 0xdf4, BIT6)) + { + i++; + if (i > 1000000) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Wait in %s() more than %d times!\n", __FUNCTION__, i)); + break; + } + } + + ODM_SetBBReg(pDM_Odm, 0xc50, 0x7f, initial_gain); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); // Set RF to CH4 & 40M + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, 0xf00000, 0xf); // 3 wire Disable 88c[23:20]=0xf + ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT14|BIT15, 0x0); //128 pt //Set PSD 128 ptss + ODM_StallExecution(3000); + + + //2 [ Doing PSD Function in (CH4)] + + //Antenna A + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Main-ant (CH4)\n")); + ODM_SetBBReg(pDM_Odm, 0x948, 0xfff, 0x200); + ODM_StallExecution(10); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("dbg\n")); + for (i=0;iPSD_report_Main[tone_idx] ) + PSD_report_Main[tone_idx]+=PSD_report_temp; + } + } + //Antenna B + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Aux-ant (CH4)\n")); + ODM_SetBBReg(pDM_Odm, 0x948, 0xfff, 0x280); + ODM_StallExecution(10); + for (i=0;iPSD_report_Aux[tone_idx] ) + PSD_report_Aux[tone_idx]+=PSD_report_temp; + } + } + //2 [ Doing PSD Function in (CH8)] + + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, 0xf00000, 0x0); // 3 wire enable 88c[23:20]=0x0 + ODM_StallExecution(3000); + + ODM_SetBBReg(pDM_Odm, 0xc50, 0x7f, initial_gain); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); // Set RF to CH8 & 40M + + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, 0xf00000, 0xf); // 3 wire Disable 88c[23:20]=0xf + ODM_StallExecution(3000); + + //Antenna A + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Main-ant (CH8)\n")); + ODM_SetBBReg(pDM_Odm, 0x948, 0xfff, 0x200); + ODM_StallExecution(10); + + for (i=0;iPSD_report_Main[tone_idx] ) + PSD_report_Main[Tone_lenth_1+tone_idx]+=PSD_report_temp; + } + } + + //Antenna B + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Aux-ant (CH8)\n")); + ODM_SetBBReg(pDM_Odm, 0x948, 0xfff, 0x280); + ODM_StallExecution(10); + + for (i=0;iPSD_report_Aux[tone_idx] ) + PSD_report_Aux[Tone_lenth_1+tone_idx]+=PSD_report_temp; + } + } + + //2 [ Calculate Result ] + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\nMain PSD Result: (ALL) \n")); + for (tone_idx=0;tone_idx<(Tone_lenth_1+Tone_lenth_2);tone_idx++) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Tone-%d]: %d, \n",(tone_idx+1), PSD_report_Main[tone_idx] )); + Main_psd_result+= PSD_report_Main[tone_idx]; + if(PSD_report_Main[tone_idx]>MAX_PSD_report_Main) + MAX_PSD_report_Main=PSD_report_Main[tone_idx]; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("--------------------------- \nTotal_Main= (( %d ))\n", Main_psd_result)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("MAX_Main = (( %d ))\n", MAX_PSD_report_Main)); + + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\nAux PSD Result: (ALL) \n")); + for (tone_idx=0;tone_idx<(Tone_lenth_1+Tone_lenth_2);tone_idx++) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Tone-%d]: %d, \n",(tone_idx+1), PSD_report_Aux[tone_idx] )); + Aux_psd_result+= PSD_report_Aux[tone_idx]; + if(PSD_report_Aux[tone_idx]>MAX_PSD_report_Aux) + MAX_PSD_report_Aux=PSD_report_Aux[tone_idx]; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("--------------------------- \nTotal_Aux= (( %d ))\n", Aux_psd_result)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("MAX_Aux = (( %d ))\n\n", MAX_PSD_report_Aux)); + + //Main_psd_result=Main_psd_result-MAX_PSD_report_Main; + //Aux_psd_result=Aux_psd_result-MAX_PSD_report_Aux; + PSD_power_threshold=(Main_psd_result*7)>>3; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Main_result , Aux_result ] = [ %d , %d ], PSD_power_threshold=(( %d ))\n", Main_psd_result, Aux_psd_result,PSD_power_threshold)); + + //3 [ Dual Antenna ] + if(Aux_psd_result >= PSD_power_threshold ) + { + if(pDM_Odm->DM_SWAT_Table.ANTB_ON == FALSE) + { + pDM_Odm->DM_SWAT_Table.ANTA_ON = TRUE; + pDM_Odm->DM_SWAT_Table.ANTB_ON = TRUE; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ODM_SwAntDivCheckBeforeLink(): Dual antenna\n")); + + // set bt coexDM from 1ant coexDM to 2ant coexDM + //BT_SetBtCoexAntNum(pAdapter, BT_COEX_ANT_TYPE_DETECTED, 2); + + // Init antenna diversity + pDM_Odm->SupportAbility |= ODM_BB_ANT_DIV; + ODM_AntDivInit(pDM_Odm); + } + //3 [ Single Antenna ] + else + { + if(pDM_Odm->DM_SWAT_Table.ANTB_ON == TRUE) + { + pDM_Odm->DM_SWAT_Table.ANTA_ON = TRUE; + pDM_Odm->DM_SWAT_Table.ANTB_ON = FALSE; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): Single antenna\n")); + } + + //2 [ Recover all parameters ] + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,Channel_ori); + ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, 0xf00000, 0x0); // 3 wire enable 88c[23:20]=0x0 + ODM_SetBBReg(pDM_Odm, 0xc50, 0x7f, Regc50); + + ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, bMaskDWord, Reg948); + ODM_SetBBReg(pDM_Odm, rAGC_table_select, bMaskDWord, Regb2c); + + ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 1); //enable whole CCK block + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0x0); //Turn on TX // Resume TX Queue + ODM_SetBBReg(pDM_Odm, 0xC14, bMaskDWord, Regc14); // [ Set IQK Matrix = 0 ] equivalent to [ Turn on CCA] + ODM_SetBBReg(pDM_Odm, 0x908, bMaskDWord, Reg908); + + return; + +} + + + + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDect.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDect.h new file mode 100755 index 000000000000..9e18c2ebfeee --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDect.h @@ -0,0 +1,76 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMANTDECT_H__ +#define __PHYDMANTDECT_H__ + +#define ANTDECT_VERSION "1.0" + +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN |ODM_CE)) +//1 [1. Single Tone Method] =================================================== + + + +VOID +ODM_SingleDualAntennaDefaultSetting( + IN PDM_ODM_T pDM_Odm + ); + +BOOLEAN +ODM_SingleDualAntennaDetection( + IN PDM_ODM_T pDM_Odm, + IN u1Byte mode + ); + +//1 [2. Scan AP RSSI Method] ================================================== + +VOID +odm_SwAntDetectInit( + IN PDM_ODM_T pDM_Odm + ); + + +#define SwAntDivCheckBeforeLink ODM_SwAntDivCheckBeforeLink + +BOOLEAN +ODM_SwAntDivCheckBeforeLink( + IN PDM_ODM_T pDM_Odm + ); + + + + +//1 [3. PSD Method] ========================================================== + + +VOID +ODM_SingleDualAntennaDetection_PSD( + IN PDM_ODM_T pDM_Odm +); + + + + + + +#endif +#endif + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDiv.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDiv.c new file mode 100755 index 000000000000..4898e9ce7db2 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDiv.c @@ -0,0 +1,2850 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ + +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +//====================================================== +// when antenna test utility is on or some testing need to disable antenna diversity +// call this function to disable all ODM related mechanisms which will switch antenna. +//====================================================== +VOID +ODM_StopAntennaSwitchDm( + IN PDM_ODM_T pDM_Odm + ) +{ + // disable ODM antenna diversity + pDM_Odm->SupportAbility &= ~ODM_BB_ANT_DIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("STOP Antenna Diversity \n")); +} + +VOID +ODM_SetAntConfig( + IN PDM_ODM_T pDM_Odm, + IN u1Byte antSetting // 0=A, 1=B, 2=C, .... + ) +{ + if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + if(antSetting == 0) // ant A + ODM_SetBBReg(pDM_Odm, 0x948, bMaskDWord, 0x00000000); + else if(antSetting == 1) + ODM_SetBBReg(pDM_Odm, 0x948, bMaskDWord, 0x00000280); + } +} + +//====================================================== + + +VOID +ODM_SwAntDivRestAfterLink( + IN PDM_ODM_T pDM_Odm + ) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte i; + + if(pDM_Odm->SupportICType == ODM_RTL8723A) + { + pDM_SWAT_Table->RSSI_cnt_A = 0; + pDM_SWAT_Table->RSSI_cnt_B = 0; + pDM_Odm->RSSI_test = FALSE; + pDM_SWAT_Table->try_flag = 0xff; + pDM_SWAT_Table->RSSI_Trying = 0; + pDM_SWAT_Table->SelectAntennaMap=0xAA; + + } + else if(pDM_Odm->SupportICType & (ODM_RTL8723B|ODM_RTL8821)) + { + pDM_Odm->RSSI_test = FALSE; + pDM_SWAT_Table->try_flag = 0xff; + pDM_SWAT_Table->RSSI_Trying = 0; + pDM_SWAT_Table->Double_chk_flag= 0; + + pDM_FatTable->RxIdleAnt=MAIN_ANT; + + for (i=0; iMainAnt_Sum[i] = 0; + pDM_FatTable->AuxAnt_Sum[i] = 0; + pDM_FatTable->MainAnt_Cnt[i] = 0; + pDM_FatTable->AuxAnt_Cnt[i] = 0; + } + + } +} + + +#if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) +VOID +odm_AntDiv_on_off( IN PDM_ODM_T pDM_Odm ,IN u1Byte swch) +{ + if(pDM_Odm->AntDivType==S0S1_SW_ANTDIV || pDM_Odm->AntDivType==CGCS_RX_SW_ANTDIV) + return; + + if(pDM_Odm->SupportICType & ODM_N_ANTDIV_SUPPORT) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("(( Turn %s )) N-Series HW-AntDiv block\n",(swch==ANTDIV_ON)?"ON" : "OFF")); + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, swch); //OFDM AntDiv function block enable + if( pDM_Odm->AntDivType != S0S1_SW_ANTDIV) + ODM_SetBBReg(pDM_Odm, 0xa00 , BIT15, swch); //CCK AntDiv function block enable + } + else if(pDM_Odm->SupportICType & ODM_AC_ANTDIV_SUPPORT) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("(( Turn %s )) AC-Series HW-AntDiv block\n",(swch==ANTDIV_ON)?"ON" : "OFF")); + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, swch); //OFDM AntDiv function block enable + //ODM_SetBBReg(pDM_Odm, 0xa00 , BIT15, swch); //CCK AntDiv function block enable + } + else + { + ODM_SetBBReg(pDM_Odm, 0x8D4 , BIT24, swch); //OFDM AntDiv function block enable + + if( (pDM_Odm->CutVersion >= ODM_CUT_C) && (pDM_Odm->SupportICType == ODM_RTL8821) && ( pDM_Odm->AntDivType != S0S1_SW_ANTDIV)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("(( Turn %s )) CCK HW-AntDiv block\n",(swch==ANTDIV_ON)?"ON" : "OFF")); + ODM_SetBBReg(pDM_Odm, 0x800 , BIT25, swch); + ODM_SetBBReg(pDM_Odm, 0xA00 , BIT15, swch); //CCK AntDiv function block enable + } + } + } +} + +VOID +ODM_UpdateRxIdleAnt(IN PDM_ODM_T pDM_Odm, IN u1Byte Ant) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte DefaultAnt, OptionalAnt,value32; + + //#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + //PADAPTER pAdapter = pDM_Odm->Adapter; + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + //#endif + + if(pDM_FatTable->RxIdleAnt != Ant) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] RxIdleAnt =%s\n",(Ant==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + + if(!(pDM_Odm->SupportICType & ODM_RTL8723B)) + pDM_FatTable->RxIdleAnt = Ant; + + if(Ant == MAIN_ANT) + { + DefaultAnt = ANT1_2G; + OptionalAnt = ANT2_2G; + } + else + { + DefaultAnt = ANT2_2G; + OptionalAnt = ANT1_2G; + } + + if(pDM_Odm->SupportICType & ODM_N_ANTDIV_SUPPORT) + { + if(pDM_Odm->SupportICType==ODM_RTL8192E) + { + ODM_SetBBReg(pDM_Odm, 0xB38 , BIT5|BIT4|BIT3, DefaultAnt); //Default RX + ODM_SetBBReg(pDM_Odm, 0xB38 , BIT8|BIT7|BIT6, OptionalAnt);//Optional RX + ODM_SetBBReg(pDM_Odm, 0x860, BIT14|BIT13|BIT12, DefaultAnt);//Default TX + } + else if(pDM_Odm->SupportICType==ODM_RTL8723B) + { + value32 = ODM_GetBBReg(pDM_Odm, 0x948, 0xFFF); + + if (value32 !=0x280) + ODM_UpdateRxIdleAnt_8723B(pDM_Odm, Ant, DefaultAnt, OptionalAnt); + else + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] 8723B: Fail to set RX antenna due to 0x948 = 0x280\n")); + } + else + { + ODM_SetBBReg(pDM_Odm, 0x864 , BIT5|BIT4|BIT3, DefaultAnt); //Default RX + ODM_SetBBReg(pDM_Odm, 0x864 , BIT8|BIT7|BIT6, OptionalAnt); //Optional RX + ODM_SetBBReg(pDM_Odm, 0x860, BIT14|BIT13|BIT12, DefaultAnt); //Default TX + } + } + else if(pDM_Odm->SupportICType & ODM_AC_ANTDIV_SUPPORT) + { + u2Byte value16 = ODM_Read2Byte(pDM_Odm, ODM_REG_TRMUX_11AC+2); + // + // 2014/01/14 MH/Luke.Lee Add direct write for register 0xc0a to prevnt + // incorrect 0xc08 bit0-15 .We still not know why it is changed. + // + value16 &= ~(BIT11|BIT10|BIT9|BIT8|BIT7|BIT6|BIT5|BIT4|BIT3); + value16 |= ((u2Byte)DefaultAnt <<3); + value16 |= ((u2Byte)OptionalAnt <<6); + value16 |= ((u2Byte)DefaultAnt <<9); + ODM_Write2Byte(pDM_Odm, ODM_REG_TRMUX_11AC+2, value16); + /* + ODM_SetBBReg(pDM_Odm, ODM_REG_TRMUX_11AC , BIT21|BIT20|BIT19, DefaultAnt); //Default RX + ODM_SetBBReg(pDM_Odm, ODM_REG_TRMUX_11AC , BIT24|BIT23|BIT22, OptionalAnt);//Optional RX + ODM_SetBBReg(pDM_Odm, ODM_REG_TRMUX_11AC , BIT27|BIT26|BIT25, DefaultAnt); //Default TX + */ + } + + if(pDM_Odm->SupportICType==ODM_RTL8188E) + { + ODM_SetMACReg(pDM_Odm, 0x6D8 , BIT7|BIT6, DefaultAnt); //PathA Resp Tx + } + else + { + ODM_SetMACReg(pDM_Odm, 0x6D8 , BIT10|BIT9|BIT8, DefaultAnt); //PathA Resp Tx + } + + } + else// pDM_FatTable->RxIdleAnt == Ant + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Stay in Ori-Ant ] RxIdleAnt =%s\n",(Ant==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + pDM_FatTable->RxIdleAnt = Ant; + } +} + + +VOID +odm_UpdateTxAnt(IN PDM_ODM_T pDM_Odm, IN u1Byte Ant, IN u4Byte MacId) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u1Byte TxAnt; + + if(Ant == MAIN_ANT) + TxAnt = ANT1_2G; + else + TxAnt = ANT2_2G; + + pDM_FatTable->antsel_a[MacId] = TxAnt&BIT0; + pDM_FatTable->antsel_b[MacId] = (TxAnt&BIT1)>>1; + pDM_FatTable->antsel_c[MacId] = (TxAnt&BIT2)>>2; + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + if (pDM_Odm->antdiv_rssi) + { + //panic_printk("[Tx from TxInfo]: MacID:(( %d )), TxAnt = (( %s ))\n",MacId,(Ant==MAIN_ANT)?"MAIN_ANT":"AUX_ANT"); + //panic_printk("antsel_tr_mux=(( 3'b%d%d%d ))\n", pDM_FatTable->antsel_c[MacId] , pDM_FatTable->antsel_b[MacId] , pDM_FatTable->antsel_a[MacId] ); + } + #endif + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Tx from TxInfo]: MacID:(( %d )), TxAnt = (( %s ))\n", + // MacId,(Ant==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("antsel_tr_mux=(( 3'b%d%d%d ))\n", + //pDM_FatTable->antsel_c[MacId] , pDM_FatTable->antsel_b[MacId] , pDM_FatTable->antsel_a[MacId] )); + +} + + + +#if (RTL8188E_SUPPORT == 1) + + +VOID +odm_RX_HWAntDiv_Init_88E( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte value32; + + pDM_Odm->AntType = ODM_AUTO_ANT; + + if(pDM_Odm->mp_mode == TRUE) + { + pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV; + ODM_SetBBReg(pDM_Odm, ODM_REG_IGI_A_11N , BIT7, 0); // disable HW AntDiv + ODM_SetBBReg(pDM_Odm, ODM_REG_LNA_SWITCH_11N , BIT31, 1); // 1:CG, 0:CS + return; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8188E AntDiv_Init => AntDivType=[CGCS_RX_HW_ANTDIV]\n")); + + //MAC Setting + value32 = ODM_GetMACReg(pDM_Odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); + ODM_SetMACReg(pDM_Odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32|(BIT23|BIT25)); //Reg4C[25]=1, Reg4C[23]=1 for pin output + //Pin Settings + ODM_SetBBReg(pDM_Odm, ODM_REG_PIN_CTRL_11N , BIT9|BIT8, 0);//Reg870[8]=1'b0, Reg870[9]=1'b0 //antsel antselb by HW + ODM_SetBBReg(pDM_Odm, ODM_REG_RX_ANT_CTRL_11N , BIT10, 0); //Reg864[10]=1'b0 //antsel2 by HW + ODM_SetBBReg(pDM_Odm, ODM_REG_LNA_SWITCH_11N , BIT22, 1); //Regb2c[22]=1'b0 //disable CS/CG switch + ODM_SetBBReg(pDM_Odm, ODM_REG_LNA_SWITCH_11N , BIT31, 1); //Regb2c[31]=1'b1 //output at CG only + //OFDM Settings + ODM_SetBBReg(pDM_Odm, ODM_REG_ANTDIV_PARA1_11N , bMaskDWord, 0x000000a0); + //CCK Settings + ODM_SetBBReg(pDM_Odm, ODM_REG_BB_PWR_SAV4_11N , BIT7, 1); //Fix CCK PHY status report issue + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_ANTDIV_PARA2_11N , BIT4, 1); //CCK complete HW AntDiv within 64 samples + + ODM_SetBBReg(pDM_Odm, ODM_REG_ANT_MAPPING1_11N , 0xFFFF, 0x0001); //antenna mapping table +} + +VOID +odm_TRX_HWAntDiv_Init_88E( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte value32; + + if(pDM_Odm->mp_mode == TRUE) + { + pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV; + ODM_SetBBReg(pDM_Odm, ODM_REG_IGI_A_11N , BIT7, 0); // disable HW AntDiv + ODM_SetBBReg(pDM_Odm, ODM_REG_RX_ANT_CTRL_11N , BIT5|BIT4|BIT3, 0); //Default RX (0/1) + return; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8188E AntDiv_Init => AntDivType=[CG_TRX_HW_ANTDIV (SPDT)]\n")); + + //MAC Setting + value32 = ODM_GetMACReg(pDM_Odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); + ODM_SetMACReg(pDM_Odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32|(BIT23|BIT25)); //Reg4C[25]=1, Reg4C[23]=1 for pin output + //Pin Settings + ODM_SetBBReg(pDM_Odm, ODM_REG_PIN_CTRL_11N , BIT9|BIT8, 0);//Reg870[8]=1'b0, Reg870[9]=1'b0 //antsel antselb by HW + ODM_SetBBReg(pDM_Odm, ODM_REG_RX_ANT_CTRL_11N , BIT10, 0); //Reg864[10]=1'b0 //antsel2 by HW + ODM_SetBBReg(pDM_Odm, ODM_REG_LNA_SWITCH_11N , BIT22, 0); //Regb2c[22]=1'b0 //disable CS/CG switch + ODM_SetBBReg(pDM_Odm, ODM_REG_LNA_SWITCH_11N , BIT31, 1); //Regb2c[31]=1'b1 //output at CG only + //OFDM Settings + ODM_SetBBReg(pDM_Odm, ODM_REG_ANTDIV_PARA1_11N , bMaskDWord, 0x000000a0); + //CCK Settings + ODM_SetBBReg(pDM_Odm, ODM_REG_BB_PWR_SAV4_11N , BIT7, 1); //Fix CCK PHY status report issue + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_ANTDIV_PARA2_11N , BIT4, 1); //CCK complete HW AntDiv within 64 samples + + //antenna mapping table + if(!pDM_Odm->bIsMPChip) //testchip + { + ODM_SetBBReg(pDM_Odm, ODM_REG_RX_DEFUALT_A_11N , BIT10|BIT9|BIT8, 1); //Reg858[10:8]=3'b001 + ODM_SetBBReg(pDM_Odm, ODM_REG_RX_DEFUALT_A_11N , BIT13|BIT12|BIT11, 2); //Reg858[13:11]=3'b010 + } + else //MPchip + ODM_SetBBReg(pDM_Odm, ODM_REG_ANT_MAPPING1_11N , bMaskDWord, 0x0001); //Reg914=3'b010, Reg915=3'b001 +} + +VOID +odm_Smart_HWAntDiv_Init_88E( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte value32, i; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte AntCombination = 2; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8188E AntDiv_Init => AntDivType=[CG_TRX_SMART_ANTDIV]\n")); + + if(pDM_Odm->mp_mode == TRUE) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("pDM_Odm->AntDivType: %d\n", pDM_Odm->AntDivType)); + return; + } + + for(i=0; i<6; i++) + { + pDM_FatTable->Bssid[i] = 0; + pDM_FatTable->antSumRSSI[i] = 0; + pDM_FatTable->antRSSIcnt[i] = 0; + pDM_FatTable->antAveRSSI[i] = 0; + } + pDM_FatTable->TrainIdx = 0; + pDM_FatTable->FAT_State = FAT_NORMAL_STATE; + + //MAC Setting + value32 = ODM_GetMACReg(pDM_Odm, 0x4c, bMaskDWord); + ODM_SetMACReg(pDM_Odm, 0x4c, bMaskDWord, value32|(BIT23|BIT25)); //Reg4C[25]=1, Reg4C[23]=1 for pin output + value32 = ODM_GetMACReg(pDM_Odm, 0x7B4, bMaskDWord); + ODM_SetMACReg(pDM_Odm, 0x7b4, bMaskDWord, value32|(BIT16|BIT17)); //Reg7B4[16]=1 enable antenna training, Reg7B4[17]=1 enable A2 match + //value32 = PlatformEFIORead4Byte(Adapter, 0x7B4); + //PlatformEFIOWrite4Byte(Adapter, 0x7b4, value32|BIT18); //append MACID in reponse packet + + //Match MAC ADDR + ODM_SetMACReg(pDM_Odm, 0x7b4, 0xFFFF, 0); + ODM_SetMACReg(pDM_Odm, 0x7b0, bMaskDWord, 0); + + ODM_SetBBReg(pDM_Odm, 0x870 , BIT9|BIT8, 0);//Reg870[8]=1'b0, Reg870[9]=1'b0 //antsel antselb by HW + ODM_SetBBReg(pDM_Odm, 0x864 , BIT10, 0); //Reg864[10]=1'b0 //antsel2 by HW + ODM_SetBBReg(pDM_Odm, 0xb2c , BIT22, 0); //Regb2c[22]=1'b0 //disable CS/CG switch + ODM_SetBBReg(pDM_Odm, 0xb2c , BIT31, 1); //Regb2c[31]=1'b1 //output at CG only + ODM_SetBBReg(pDM_Odm, 0xca4 , bMaskDWord, 0x000000a0); + + //antenna mapping table + if(AntCombination == 2) + { + if(!pDM_Odm->bIsMPChip) //testchip + { + ODM_SetBBReg(pDM_Odm, 0x858 , BIT10|BIT9|BIT8, 1); //Reg858[10:8]=3'b001 + ODM_SetBBReg(pDM_Odm, 0x858 , BIT13|BIT12|BIT11, 2); //Reg858[13:11]=3'b010 + } + else //MPchip + { + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte0, 1); + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte1, 2); + } + } + else if(AntCombination == 7) + { + if(!pDM_Odm->bIsMPChip) //testchip + { + ODM_SetBBReg(pDM_Odm, 0x858 , BIT10|BIT9|BIT8, 0); //Reg858[10:8]=3'b000 + ODM_SetBBReg(pDM_Odm, 0x858 , BIT13|BIT12|BIT11, 1); //Reg858[13:11]=3'b001 + ODM_SetBBReg(pDM_Odm, 0x878 , BIT16, 0); + ODM_SetBBReg(pDM_Odm, 0x858 , BIT15|BIT14, 2); //(Reg878[0],Reg858[14:15])=3'b010 + ODM_SetBBReg(pDM_Odm, 0x878 , BIT19|BIT18|BIT17, 3);//Reg878[3:1]=3b'011 + ODM_SetBBReg(pDM_Odm, 0x878 , BIT22|BIT21|BIT20, 4);//Reg878[6:4]=3b'100 + ODM_SetBBReg(pDM_Odm, 0x878 , BIT25|BIT24|BIT23, 5);//Reg878[9:7]=3b'101 + ODM_SetBBReg(pDM_Odm, 0x878 , BIT28|BIT27|BIT26, 6);//Reg878[12:10]=3b'110 + ODM_SetBBReg(pDM_Odm, 0x878 , BIT31|BIT30|BIT29, 7);//Reg878[15:13]=3b'111 + } + else //MPchip + { + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte0, 0); + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte1, 1); + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte2, 2); + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte3, 3); + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte0, 4); + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte1, 5); + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte2, 6); + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte3, 7); + } + } + + //Default Ant Setting when no fast training + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, 1); //Reg80c[21]=1'b1 //from TX Info + ODM_SetBBReg(pDM_Odm, 0x864 , BIT5|BIT4|BIT3, 0); //Default RX + ODM_SetBBReg(pDM_Odm, 0x864 , BIT8|BIT7|BIT6, 1); //Optional RX + //ODM_SetBBReg(pDM_Odm, 0x860 , BIT14|BIT13|BIT12, 1); //Default TX + + //Enter Traing state + ODM_SetBBReg(pDM_Odm, 0x864 , BIT2|BIT1|BIT0, (AntCombination-1)); //Reg864[2:0]=3'd6 //ant combination=reg864[2:0]+1 + //ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, 0); //RegC50[7]=1'b0 //disable HW AntDiv + //ODM_SetBBReg(pDM_Odm, 0xe08 , BIT16, 0); //RegE08[16]=1'b0 //disable fast training + //ODM_SetBBReg(pDM_Odm, 0xe08 , BIT16, 1); //RegE08[16]=1'b1 //enable fast training + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, 1); //RegC50[7]=1'b1 //enable HW AntDiv + + //SW Control + //PHY_SetBBReg(Adapter, 0x864 , BIT10, 1); + //PHY_SetBBReg(Adapter, 0x870 , BIT9, 1); + //PHY_SetBBReg(Adapter, 0x870 , BIT8, 1); + //PHY_SetBBReg(Adapter, 0x864 , BIT11, 1); + //PHY_SetBBReg(Adapter, 0x860 , BIT9, 0); + //PHY_SetBBReg(Adapter, 0x860 , BIT8, 0); +} +#endif //#if (RTL8188E_SUPPORT == 1) + + +#if (RTL8192E_SUPPORT == 1) +VOID +odm_RX_HWAntDiv_Init_92E( + IN PDM_ODM_T pDM_Odm +) +{ + + if(pDM_Odm->mp_mode == TRUE) + { + //pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV; + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT8, 0); //r_rxdiv_enable_anta Regc50[8]=1'b0 0: control by c50[9] + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT9, 1); // 1:CG, 0:CS + return; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8192E AntDiv_Init => AntDivType=[CGCS_RX_HW_ANTDIV]\n")); + + //Pin Settings + ODM_SetBBReg(pDM_Odm, 0x870 , BIT8, 0);//Reg870[8]=1'b0, // "antsel" is controled by HWs + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT8, 1); //Regc50[8]=1'b1 //" CS/CG switching" is controled by HWs + + //Mapping table + ODM_SetBBReg(pDM_Odm, 0x914 , 0xFFFF, 0x0100); //antenna mapping table + + //OFDM Settings + ODM_SetBBReg(pDM_Odm, 0xca4 , 0x7FF, 0xA0); //thershold + ODM_SetBBReg(pDM_Odm, 0xca4 , 0x7FF000, 0x0); //bias + + //CCK Settings + ODM_SetBBReg(pDM_Odm, 0xa04 , 0xF000000, 0); //Select which path to receive for CCK_1 & CCK_2 + ODM_SetBBReg(pDM_Odm, 0xb34 , BIT30, 1); //(92E) ANTSEL_CCK_opt = r_en_antsel_cck? ANTSEL_CCK: 1'b0 + ODM_SetBBReg(pDM_Odm, 0xa74 , BIT7, 1); //Fix CCK PHY status report issue + ODM_SetBBReg(pDM_Odm, 0xa0c , BIT4, 1); //CCK complete HW AntDiv within 64 samples +} + +VOID +odm_TRX_HWAntDiv_Init_92E( + IN PDM_ODM_T pDM_Odm +) +{ + + if(pDM_Odm->mp_mode == TRUE) + { + //pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV; + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT8, 0); //r_rxdiv_enable_anta Regc50[8]=1'b0 0: control by c50[9] + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT9, 1); // 1:CG, 0:CS + return; + } + +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + pDM_Odm->antdiv_rssi=0; +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8192E AntDiv_Init => AntDivType=[CG_TRX_HW_ANTDIV]\n")); + + //3 --RFE pin setting--------- + //[MAC] + ODM_SetMACReg(pDM_Odm, 0x38, BIT11, 1); //DBG PAD Driving control (GPIO 8) + ODM_SetMACReg(pDM_Odm, 0x4c, BIT23, 0); //path-A , RFE_CTRL_3 & RFE_CTRL_4 + //[BB] + ODM_SetBBReg(pDM_Odm, 0x944 , BIT4|BIT3, 0x3); //RFE_buffer + ODM_SetBBReg(pDM_Odm, 0x940 , BIT7|BIT6, 0x0); // r_rfe_path_sel_ (RFE_CTRL_3) + ODM_SetBBReg(pDM_Odm, 0x940 , BIT9|BIT8, 0x0); // r_rfe_path_sel_ (RFE_CTRL_4) + ODM_SetBBReg(pDM_Odm, 0x944 , BIT31, 0); //RFE_buffer + ODM_SetBBReg(pDM_Odm, 0x92C , BIT3, 0); //rfe_inv (RFE_CTRL_3) + ODM_SetBBReg(pDM_Odm, 0x92C , BIT4, 1); //rfe_inv (RFE_CTRL_4) + ODM_SetBBReg(pDM_Odm, 0x930 , 0xFF000, 0x88); //path-A , RFE_CTRL_3 & 4=> ANTSEL[0] + //3 ------------------------- + + //Pin Settings + ODM_SetBBReg(pDM_Odm, 0xC50 , BIT8, 0); //path-A //disable CS/CG switch + ODM_SetBBReg(pDM_Odm, 0xC50 , BIT9, 1); //path-A //output at CG only + ODM_SetBBReg(pDM_Odm, 0x870 , BIT9|BIT8, 0); //path-A //antsel antselb by HW + ODM_SetBBReg(pDM_Odm, 0xB38 , BIT10, 0); //path-A //antsel2 by HW + + //Mapping table + ODM_SetBBReg(pDM_Odm, 0x914 , 0xFFFF, 0x0100); //antenna mapping table + + //OFDM Settings + ODM_SetBBReg(pDM_Odm, 0xca4 , 0x7FF, 0xA0); //thershold + ODM_SetBBReg(pDM_Odm, 0xca4 , 0x7FF000, 0x0); //bias + + //CCK Settings + ODM_SetBBReg(pDM_Odm, 0xa04 , 0xF000000, 0); //Select which path to receive for CCK_1 & CCK_2 + ODM_SetBBReg(pDM_Odm, 0xb34 , BIT30, 1); //(92E) ANTSEL_CCK_opt = r_en_antsel_cck? ANTSEL_CCK: 1'b0 + ODM_SetBBReg(pDM_Odm, 0xa74 , BIT7, 1); //Fix CCK PHY status report issue + ODM_SetBBReg(pDM_Odm, 0xa0c , BIT4, 1); //CCK complete HW AntDiv within 64 samples + + //Timming issue + ODM_SetBBReg(pDM_Odm, 0xE20 , BIT23|BIT22|BIT21|BIT20, 8); //keep antidx after tx for ACK ( unit x 32 mu sec) +} + +VOID +odm_Smart_HWAntDiv_Init_92E( + IN PDM_ODM_T pDM_Odm +) +{ + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8188E AntDiv_Init => AntDivType=[CG_TRX_SMART_ANTDIV]\n")); +} +#endif //#if (RTL8192E_SUPPORT == 1) + + +#if (RTL8723B_SUPPORT == 1) +VOID +odm_TRX_HWAntDiv_Init_8723B( + IN PDM_ODM_T pDM_Odm +) +{ + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8723B AntDiv_Init => AntDivType=[CG_TRX_HW_ANTDIV(DPDT)]\n")); + + //Mapping Table + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte0, 0); + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte1, 1); + + //OFDM HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0xCA4 , 0x7FF, 0xa0); //thershold + ODM_SetBBReg(pDM_Odm, 0xCA4 , 0x7FF000, 0x00); //bias + + //CCK HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0xA74 , BIT7, 1); //patch for clk from 88M to 80M + ODM_SetBBReg(pDM_Odm, 0xA0C , BIT4, 1); //do 64 samples + + //BT Coexistence + ODM_SetBBReg(pDM_Odm, 0x864, BIT12, 0); //keep antsel_map when GNT_BT = 1 + ODM_SetBBReg(pDM_Odm, 0x874 , BIT23, 0); //Disable hw antsw & fast_train.antsw when GNT_BT=1 + + //Output Pin Settings + ODM_SetBBReg(pDM_Odm, 0x870 , BIT8, 0); // + + ODM_SetBBReg(pDM_Odm, 0x948 , BIT6, 0); //WL_BB_SEL_BTG_TRXG_anta, (1: HW CTRL 0: SW CTRL) + ODM_SetBBReg(pDM_Odm, 0x948 , BIT7, 0); + + ODM_SetMACReg(pDM_Odm, 0x40 , BIT3, 1); + ODM_SetMACReg(pDM_Odm, 0x38 , BIT11, 1); + ODM_SetMACReg(pDM_Odm, 0x4C , BIT24|BIT23, 2); //select DPDT_P and DPDT_N as output pin + + ODM_SetBBReg(pDM_Odm, 0x944 , BIT0|BIT1, 3); //in/out + ODM_SetBBReg(pDM_Odm, 0x944 , BIT31, 0); // + + ODM_SetBBReg(pDM_Odm, 0x92C , BIT1, 0); //DPDT_P non-inverse + ODM_SetBBReg(pDM_Odm, 0x92C , BIT0, 1); //DPDT_N inverse + + ODM_SetBBReg(pDM_Odm, 0x930 , 0xF0, 8); // DPDT_P = ANTSEL[0] + ODM_SetBBReg(pDM_Odm, 0x930 , 0xF, 8); // DPDT_N = ANTSEL[0] + + //Timming issue + ODM_SetBBReg(pDM_Odm, 0xE20 , BIT23|BIT22|BIT21|BIT20, 8); //keep antidx after tx for ACK ( unit x 32 mu sec) + + //2 [--For HW Bug Setting] + if(pDM_Odm->AntType == ODM_AUTO_ANT) + ODM_SetBBReg(pDM_Odm, 0xA00 , BIT15, 0); //CCK AntDiv function block enable + + //ODM_SetBBReg(pDM_Odm, 0x80C , BIT21, 0); //TX Ant by Reg + + +} + + + +VOID +odm_S0S1_SWAntDiv_Init_8723B( + IN PDM_ODM_T pDM_Odm +) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8723B AntDiv_Init => AntDivType=[ S0S1_SW_AntDiv] \n")); + + //Mapping Table + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte0, 0); + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte1, 1); + + //Output Pin Settings + //ODM_SetBBReg(pDM_Odm, 0x948 , BIT6, 0x1); + ODM_SetBBReg(pDM_Odm, 0x870 , BIT9|BIT8, 0); + + pDM_FatTable->bBecomeLinked =FALSE; + pDM_SWAT_Table->try_flag = 0xff; + pDM_SWAT_Table->Double_chk_flag = 0; + pDM_SWAT_Table->TrafficLoad = TRAFFIC_LOW; + + //Timming issue + ODM_SetBBReg(pDM_Odm, 0xE20 , BIT23|BIT22|BIT21|BIT20, 8); //keep antidx after tx for ACK ( unit x 32 mu sec) + + //2 [--For HW Bug Setting] + ODM_SetBBReg(pDM_Odm, 0x80C , BIT21, 0); //TX Ant by Reg + +} + +VOID +odm_S0S1_SWAntDiv_Reset_8723B( + IN PDM_ODM_T pDM_Odm +) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + pDM_FatTable->bBecomeLinked =FALSE; + pDM_SWAT_Table->try_flag = 0xff; + pDM_SWAT_Table->Double_chk_flag = 0; + pDM_SWAT_Table->TrafficLoad = TRAFFIC_LOW; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_S0S1_SWAntDiv_Reset_8723B(): pDM_FatTable->bBecomeLinked = %d\n", pDM_FatTable->bBecomeLinked)); +} + +VOID +ODM_UpdateRxIdleAnt_8723B( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Ant, + IN u4Byte DefaultAnt, + IN u4Byte OptionalAnt +) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + PADAPTER pAdapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u1Byte count=0; + u1Byte u1Temp; + u1Byte H2C_Parameter; + u4Byte value32; + + if(!pDM_Odm->bLinked) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] 8723B: Fail to set RX antenna due to no link\n")); + return; + } + + // Send H2C command to FW + // Enable wifi calibration + H2C_Parameter = TRUE; + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_WIFI_CALIBRATION, 1, &H2C_Parameter); + + // Check if H2C command sucess or not (0x1e6) + u1Temp = ODM_Read1Byte(pDM_Odm, 0x1e6); + while((u1Temp != 0x1) && (count < 100)) + { + ODM_delay_us(10); + u1Temp = ODM_Read1Byte(pDM_Odm, 0x1e6); + count++; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] 8723B: H2C command status = %d, count = %d\n", u1Temp, count)); + + if(u1Temp == 0x1) + { + // Check if BT is doing IQK (0x1e7) + count = 0; + u1Temp = ODM_Read1Byte(pDM_Odm, 0x1e7); + while((!(u1Temp & BIT0)) && (count < 100)) + { + ODM_delay_us(50); + u1Temp = ODM_Read1Byte(pDM_Odm, 0x1e7); + count++; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] 8723B: BT IQK status = %d, count = %d\n", u1Temp, count)); + + if(u1Temp & BIT0) + { + ODM_SetBBReg(pDM_Odm, 0x948 , BIT6, 0x1); + ODM_SetBBReg(pDM_Odm, 0x948 , BIT9, DefaultAnt); + ODM_SetBBReg(pDM_Odm, 0x864 , BIT5|BIT4|BIT3, DefaultAnt); //Default RX + ODM_SetBBReg(pDM_Odm, 0x864 , BIT8|BIT7|BIT6, OptionalAnt); //Optional RX + ODM_SetBBReg(pDM_Odm, 0x860, BIT14|BIT13|BIT12, DefaultAnt); //Default TX + pDM_FatTable->RxIdleAnt = Ant; + + // Set TX AGC by S0/S1 + // Need to consider Linux driver +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pAdapter->HalFunc.SetTxPowerLevelHandler(pAdapter, pHalData->CurrentChannel); +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + rtw_hal_set_tx_power_level(pAdapter, pHalData->CurrentChannel); +#endif + + // Set IQC by S0/S1 + ODM_SetIQCbyRFpath(pDM_Odm,DefaultAnt); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] 8723B: Sucess to set RX antenna\n")); + } + else + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] 8723B: Fail to set RX antenna due to BT IQK\n")); + } + else + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Ant ] 8723B: Fail to set RX antenna due to H2C command fail\n")); + + // Send H2C command to FW + // Disable wifi calibration + H2C_Parameter = FALSE; + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_WIFI_CALIBRATION, 1, &H2C_Parameter); + +} + +#endif //#if (RTL8723B_SUPPORT == 1) + +#if (RTL8821A_SUPPORT == 1) +VOID +odm_TRX_HWAntDiv_Init_8821A( + IN PDM_ODM_T pDM_Odm +) +{ + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + PADAPTER pAdapter = pDM_Odm->Adapter; + pAdapter->HalFunc.GetHalDefVarHandler(pAdapter, HAL_DEF_5G_ANT_SELECT, (pu1Byte)(&pDM_Odm->AntType)); +#else + pDM_Odm->AntType = ODM_AUTO_ANT; +#endif + pAdapter->HalFunc.GetHalDefVarHandler(pAdapter, HAL_DEF_5G_ANT_SELECT, (pu1Byte)(&pDM_Odm->AntType)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8821A AntDiv_Init => AntDivType=[ CG_TRX_HW_ANTDIV (DPDT)] \n")); + + //Output Pin Settings + ODM_SetMACReg(pDM_Odm, 0x4C , BIT25, 0); + + ODM_SetMACReg(pDM_Odm, 0x64 , BIT29, 1); //PAPE by WLAN control + ODM_SetMACReg(pDM_Odm, 0x64 , BIT28, 1); //LNAON by WLAN control + + ODM_SetBBReg(pDM_Odm, 0xCB0 , bMaskDWord, 0x77775745); + ODM_SetBBReg(pDM_Odm, 0xCB8 , BIT16, 0); + + ODM_SetMACReg(pDM_Odm, 0x4C , BIT23, 0); //select DPDT_P and DPDT_N as output pin + ODM_SetMACReg(pDM_Odm, 0x4C , BIT24, 1); //by WLAN control + ODM_SetBBReg(pDM_Odm, 0xCB4 , 0xF, 8); // DPDT_P = ANTSEL[0] + ODM_SetBBReg(pDM_Odm, 0xCB4 , 0xF0, 8); // DPDT_N = ANTSEL[0] + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT29, 0); //DPDT_P non-inverse + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT28, 1); //DPDT_N inverse + + //Mapping Table + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte0, 0); + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte1, 1); + + //Set ANT1_8821A as MAIN_ANT + if((pDM_Odm->AntType == ODM_FIX_MAIN_ANT) || (pDM_Odm->AntType == ODM_AUTO_ANT)) + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + else + ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT); + + //OFDM HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF, 0xA0); //thershold + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF000, 0x10); //bias + + //CCK HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0xA74 , BIT7, 1); //patch for clk from 88M to 80M + ODM_SetBBReg(pDM_Odm, 0xA0C , BIT4, 1); //do 64 samples + + ODM_SetBBReg(pDM_Odm, 0x800 , BIT25, 0); //ANTSEL_CCK sent to the smart_antenna circuit + ODM_SetBBReg(pDM_Odm, 0xA00 , BIT15, 0); //CCK AntDiv function block enable + + //BT Coexistence + ODM_SetBBReg(pDM_Odm, 0xCAC , BIT9, 1); //keep antsel_map when GNT_BT = 1 + ODM_SetBBReg(pDM_Odm, 0x804 , BIT4, 1); //Disable hw antsw & fast_train.antsw when GNT_BT=1 + + //Timming issue + ODM_SetBBReg(pDM_Odm, 0x818 , BIT23|BIT22|BIT21|BIT20, 8); //keep antidx after tx for ACK ( unit x 32 mu sec) + ODM_SetBBReg(pDM_Odm, 0x8CC , BIT20|BIT19|BIT18, 3); //settling time of antdiv by RF LNA = 100ns + + //response TX ant by RX ant + ODM_SetMACReg(pDM_Odm, 0x668 , BIT3, 1); + + + +} + +VOID +odm_S0S1_SWAntDiv_Init_8821A( + IN PDM_ODM_T pDM_Odm +) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + PADAPTER pAdapter = pDM_Odm->Adapter; + pAdapter->HalFunc.GetHalDefVarHandler(pAdapter, HAL_DEF_5G_ANT_SELECT, (pu1Byte)(&pDM_Odm->AntType)); +#else + pDM_Odm->AntType = ODM_AUTO_ANT; +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8821A AntDiv_Init => AntDivType=[ S0S1_SW_AntDiv] \n")); + + //Output Pin Settings + ODM_SetMACReg(pDM_Odm, 0x4C , BIT25, 0); + + ODM_SetMACReg(pDM_Odm, 0x64 , BIT29, 1); //PAPE by WLAN control + ODM_SetMACReg(pDM_Odm, 0x64 , BIT28, 1); //LNAON by WLAN control + + ODM_SetBBReg(pDM_Odm, 0xCB0 , bMaskDWord, 0x77775745); + ODM_SetBBReg(pDM_Odm, 0xCB8 , BIT16, 0); + + ODM_SetMACReg(pDM_Odm, 0x4C , BIT23, 0); //select DPDT_P and DPDT_N as output pin + ODM_SetMACReg(pDM_Odm, 0x4C , BIT24, 1); //by WLAN control + ODM_SetBBReg(pDM_Odm, 0xCB4 , 0xF, 8); // DPDT_P = ANTSEL[0] + ODM_SetBBReg(pDM_Odm, 0xCB4 , 0xF0, 8); // DPDT_N = ANTSEL[0] + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT29, 0); //DPDT_P non-inverse + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT28, 1); //DPDT_N inverse + + //Mapping Table + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte0, 0); + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte1, 1); + + //Set ANT1_8821A as MAIN_ANT + if((pDM_Odm->AntType == ODM_FIX_MAIN_ANT) || (pDM_Odm->AntType == ODM_AUTO_ANT)) + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + else + ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT); + + //OFDM HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF, 0xA0); //thershold + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF000, 0x10); //bias + + //CCK HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0xA74 , BIT7, 1); //patch for clk from 88M to 80M + ODM_SetBBReg(pDM_Odm, 0xA0C , BIT4, 1); //do 64 samples + + ODM_SetBBReg(pDM_Odm, 0x800 , BIT25, 0); //ANTSEL_CCK sent to the smart_antenna circuit + ODM_SetBBReg(pDM_Odm, 0xA00 , BIT15, 0); //CCK AntDiv function block enable + + //BT Coexistence + ODM_SetBBReg(pDM_Odm, 0xCAC , BIT9, 1); //keep antsel_map when GNT_BT = 1 + ODM_SetBBReg(pDM_Odm, 0x804 , BIT4, 1); //Disable hw antsw & fast_train.antsw when GNT_BT=1 + + //Timming issue + ODM_SetBBReg(pDM_Odm, 0x818 , BIT23|BIT22|BIT21|BIT20, 8); //keep antidx after tx for ACK ( unit x 32 mu sec) + ODM_SetBBReg(pDM_Odm, 0x8CC , BIT20|BIT19|BIT18, 3); //settling time of antdiv by RF LNA = 100ns + + //response TX ant by RX ant + ODM_SetMACReg(pDM_Odm, 0x668 , BIT3, 1); + + + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, 0); + + pDM_SWAT_Table->try_flag = 0xff; + pDM_SWAT_Table->Double_chk_flag = 0; + pDM_SWAT_Table->TrafficLoad = TRAFFIC_LOW; + pDM_SWAT_Table->CurAntenna = MAIN_ANT; + pDM_SWAT_Table->PreAntenna = MAIN_ANT; + pDM_SWAT_Table->SWAS_NoLink_State = 0; + +} +#endif //#if (RTL8821A_SUPPORT == 1) + +#if (RTL8881A_SUPPORT == 1) +VOID +odm_RX_HWAntDiv_Init_8881A( + IN PDM_ODM_T pDM_Odm +) +{ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8881A AntDiv_Init => AntDivType=[ CGCS_RX_HW_ANTDIV] \n")); + +} + +VOID +odm_TRX_HWAntDiv_Init_8881A( + IN PDM_ODM_T pDM_Odm +) +{ + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8881A AntDiv_Init => AntDivType=[ CG_TRX_HW_ANTDIV (SPDT)] \n")); + + //Output Pin Settings + // [SPDT related] + ODM_SetMACReg(pDM_Odm, 0x4C , BIT25, 0); + ODM_SetMACReg(pDM_Odm, 0x4C , BIT26, 0); + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT31, 0); //delay buffer + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT22, 0); + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT24, 1); + ODM_SetBBReg(pDM_Odm, 0xCB0 , 0xF00, 8); // DPDT_P = ANTSEL[0] + ODM_SetBBReg(pDM_Odm, 0xCB0 , 0xF0000, 8); // DPDT_N = ANTSEL[0] + + //Mapping Table + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte0, 0); + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte1, 1); + + //OFDM HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF, 0xA0); //thershold + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF000, 0x0); //bias + ODM_SetBBReg(pDM_Odm, 0x8CC , BIT20|BIT19|BIT18, 3); //settling time of antdiv by RF LNA = 100ns + + //CCK HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0xA74 , BIT7, 1); //patch for clk from 88M to 80M + ODM_SetBBReg(pDM_Odm, 0xA0C , BIT4, 1); //do 64 samples + + //Timming issue + ODM_SetBBReg(pDM_Odm, 0x818 , BIT23|BIT22|BIT21|BIT20, 8); //keep antidx after tx for ACK ( unit x 32 mu sec) + + //2 [--For HW Bug Setting] + + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, 0); //TX Ant by Reg // A-cut bug +} + +#endif //#if (RTL8881A_SUPPORT == 1) + + +#if (RTL8812A_SUPPORT == 1) +VOID +odm_TRX_HWAntDiv_Init_8812A( + IN PDM_ODM_T pDM_Odm +) +{ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8812A AntDiv_Init => AntDivType=[ CG_TRX_HW_ANTDIV (SPDT)] \n")); + + //3 //3 --RFE pin setting--------- + //[BB] + ODM_SetBBReg(pDM_Odm, 0x900 , BIT10|BIT9|BIT8, 0x0); //disable SW switch + ODM_SetBBReg(pDM_Odm, 0x900 , BIT17|BIT16, 0x0); + ODM_SetBBReg(pDM_Odm, 0x974 , BIT7|BIT6, 0x3); // in/out + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT31, 0); //delay buffer + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT26, 0); + ODM_SetBBReg(pDM_Odm, 0xCB4 , BIT27, 1); + ODM_SetBBReg(pDM_Odm, 0xCB0 , 0xF000000, 8); // DPDT_P = ANTSEL[0] + ODM_SetBBReg(pDM_Odm, 0xCB0 , 0xF0000000, 8); // DPDT_N = ANTSEL[0] + //3 ------------------------- + + //Mapping Table + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte0, 0); + ODM_SetBBReg(pDM_Odm, 0xCA4 , bMaskByte1, 1); + + //OFDM HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF, 0xA0); //thershold + ODM_SetBBReg(pDM_Odm, 0x8D4 , 0x7FF000, 0x0); //bias + ODM_SetBBReg(pDM_Odm, 0x8CC , BIT20|BIT19|BIT18, 3); //settling time of antdiv by RF LNA = 100ns + + //CCK HW AntDiv Parameters + ODM_SetBBReg(pDM_Odm, 0xA74 , BIT7, 1); //patch for clk from 88M to 80M + ODM_SetBBReg(pDM_Odm, 0xA0C , BIT4, 1); //do 64 samples + + //Timming issue + ODM_SetBBReg(pDM_Odm, 0x818 , BIT23|BIT22|BIT21|BIT20, 8); //keep antidx after tx for ACK ( unit x 32 mu sec) + + //2 [--For HW Bug Setting] + + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, 0); //TX Ant by Reg // A-cut bug + +} + +#endif //#if (RTL8812A_SUPPORT == 1) + +VOID +odm_HW_AntDiv( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i,MinMaxRSSI=0xFF, AntDivMaxRSSI=0, MaxRSSI=0, LocalMaxRSSI; + u4Byte Main_RSSI, Aux_RSSI, pkt_ratio_m=0, pkt_ratio_a=0,pkt_threshold=10; + u1Byte RxIdleAnt=0, TargetAnt=7; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + PSTA_INFO_T pEntry; + + if(!pDM_Odm->bLinked) //bLinked==False + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[No Link!!!]\n")); + + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if (pDM_Odm->antdiv_rssi) + panic_printk("[No Link!!!]\n"); + #endif + + if(pDM_FatTable->bBecomeLinked == TRUE) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + + pDM_FatTable->bBecomeLinked = pDM_Odm->bLinked; + } + return; + } + else + { + if(pDM_FatTable->bBecomeLinked ==FALSE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Linked !!!]\n")); + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); + //if(pDM_Odm->SupportICType == ODM_RTL8821 ) + //ODM_SetBBReg(pDM_Odm, 0x800 , BIT25, 0); //CCK AntDiv function disable + + //#if(DM_ODM_SUPPORT_TYPE == ODM_AP) + //else if(pDM_Odm->SupportICType == ODM_RTL8881 ) + // ODM_SetBBReg(pDM_Odm, 0x800 , BIT25, 0); //CCK AntDiv function disable + //#endif + + //else if(pDM_Odm->SupportICType == ODM_RTL8723B ||pDM_Odm->SupportICType == ODM_RTL8812) + //ODM_SetBBReg(pDM_Odm, 0xA00 , BIT15, 0); //CCK AntDiv function disable + + pDM_FatTable->bBecomeLinked = pDM_Odm->bLinked; + + if(pDM_Odm->SupportICType==ODM_RTL8723B && pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) + { + ODM_SetBBReg(pDM_Odm, 0x930 , 0xF0, 8); // DPDT_P = ANTSEL[0] // for 8723B AntDiv function patch. BB Dino 130412 + ODM_SetBBReg(pDM_Odm, 0x930 , 0xF, 8); // DPDT_N = ANTSEL[0] + } + } + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n[HW AntDiv] Start =>\n")); + + for (i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pEntry)) + { + //2 Caculate RSSI per Antenna + Main_RSSI = (pDM_FatTable->MainAnt_Cnt[i]!=0)?(pDM_FatTable->MainAnt_Sum[i]/pDM_FatTable->MainAnt_Cnt[i]):0; + Aux_RSSI = (pDM_FatTable->AuxAnt_Cnt[i]!=0)?(pDM_FatTable->AuxAnt_Sum[i]/pDM_FatTable->AuxAnt_Cnt[i]):0; + TargetAnt = (Main_RSSI==Aux_RSSI)?pDM_FatTable->RxIdleAnt:((Main_RSSI>=Aux_RSSI)?MAIN_ANT:AUX_ANT); + /* + if( pDM_FatTable->MainAnt_Cnt[i]!=0 && pDM_FatTable->AuxAnt_Cnt[i]!=0 ) + { + pkt_ratio_m=( pDM_FatTable->MainAnt_Cnt[i] / pDM_FatTable->AuxAnt_Cnt[i] ); + pkt_ratio_a=( pDM_FatTable->AuxAnt_Cnt[i] / pDM_FatTable->MainAnt_Cnt[i] ); + + if (pkt_ratio_m >= pkt_threshold) + TargetAnt=MAIN_ANT; + + else if(pkt_ratio_a >= pkt_threshold) + TargetAnt=AUX_ANT; + } + */ + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("*** SupportICType=[%lu] \n",pDM_Odm->SupportICType)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Main_Cnt = (( %d )) , Main_RSSI= (( %d )) \n", pDM_FatTable->MainAnt_Cnt[i], Main_RSSI)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Aux_Cnt = (( %d )) , Aux_RSSI = (( %d )) \n", pDM_FatTable->AuxAnt_Cnt[i] , Aux_RSSI )); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** MAC ID:[ %d ] , TargetAnt = (( %s )) \n", i ,( TargetAnt ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("*** Phy_AntSel_A=[ %d, %d, %d] \n",((pDM_Odm->DM_FatTable.antsel_rx_keep_0)&BIT2)>>2, + ((pDM_Odm->DM_FatTable.antsel_rx_keep_0)&BIT1) >>1, ((pDM_Odm->DM_FatTable.antsel_rx_keep_0)&BIT0))); + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if (pDM_Odm->antdiv_rssi) + { + panic_printk("*** SupportICType=[%lu] \n",pDM_Odm->SupportICType); + //panic_printk("*** Phy_AntSel_A=[ %d, %d, %d] \n",((pDM_Odm->DM_FatTable.antsel_rx_keep_0)&BIT2)>>2, + // ((pDM_Odm->DM_FatTable.antsel_rx_keep_0)&BIT1) >>1, ((pDM_Odm->DM_FatTable.antsel_rx_keep_0)&BIT0)); + //panic_printk("*** Phy_AntSel_B=[ %d, %d, %d] \n",((pDM_Odm->DM_FatTable.antsel_rx_keep_1)&BIT2)>>2, + // ((pDM_Odm->DM_FatTable.antsel_rx_keep_1)&BIT1) >>1, ((pDM_Odm->DM_FatTable.antsel_rx_keep_1)&BIT0)) + panic_printk("*** Client[ %lu ] , Main_Cnt = (( %lu )) , Main_RSSI= (( %lu )) \n",i, pDM_FatTable->MainAnt_Cnt[i], Main_RSSI); + panic_printk("*** Client[ %lu ] , Aux_Cnt = (( %lu )) , Aux_RSSI = (( %lu )) \n" ,i, pDM_FatTable->AuxAnt_Cnt[i] , Aux_RSSI); + } + #endif + + + LocalMaxRSSI = (Main_RSSI>Aux_RSSI)?Main_RSSI:Aux_RSSI; + //2 Select MaxRSSI for DIG + if((LocalMaxRSSI > AntDivMaxRSSI) && (LocalMaxRSSI < 40)) + AntDivMaxRSSI = LocalMaxRSSI; + if(LocalMaxRSSI > MaxRSSI) + MaxRSSI = LocalMaxRSSI; + + //2 Select RX Idle Antenna + if ( (LocalMaxRSSI != 0) && (LocalMaxRSSI < MinMaxRSSI) ) + { + RxIdleAnt = TargetAnt; + MinMaxRSSI = LocalMaxRSSI; + } + /* + if((pDM_FatTable->RxIdleAnt == MAIN_ANT) && (Main_RSSI == 0)) + Main_RSSI = Aux_RSSI; + else if((pDM_FatTable->RxIdleAnt == AUX_ANT) && (Aux_RSSI == 0)) + Aux_RSSI = Main_RSSI; + + LocalMinRSSI = (Main_RSSI>Aux_RSSI)?Aux_RSSI:Main_RSSI; + if(LocalMinRSSI < MinRSSI) + { + MinRSSI = LocalMinRSSI; + RxIdleAnt = TargetAnt; + } + */ + //2 Select TX Antenna + + #if TX_BY_REG + + #else + if(pDM_Odm->AntDivType != CGCS_RX_HW_ANTDIV) + odm_UpdateTxAnt(pDM_Odm, TargetAnt, i); + #endif + + } + pDM_FatTable->MainAnt_Sum[i] = 0; + pDM_FatTable->AuxAnt_Sum[i] = 0; + pDM_FatTable->MainAnt_Cnt[i] = 0; + pDM_FatTable->AuxAnt_Cnt[i] = 0; + } + + //2 Set RX Idle Antenna + ODM_UpdateRxIdleAnt(pDM_Odm, RxIdleAnt); + + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if (pDM_Odm->antdiv_rssi) + panic_printk("*** RxIdleAnt = (( %s )) \n \n", ( RxIdleAnt ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT"); + #endif + + if(AntDivMaxRSSI == 0) + pDM_DigTable->AntDiv_RSSI_max = pDM_Odm->RSSI_Min; + else + pDM_DigTable->AntDiv_RSSI_max = AntDivMaxRSSI; + pDM_DigTable->RSSI_max = MaxRSSI; +} + + + +#if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) +VOID +odm_S0S1_SwAntDiv( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Step + ) +{ + u4Byte i,MinMaxRSSI=0xFF, LocalMaxRSSI,LocalMinRSSI; + u4Byte Main_RSSI, Aux_RSSI; + u1Byte reset_period=10, SWAntDiv_threshold=35; + u1Byte HighTraffic_TrainTime_U=0x32,HighTraffic_TrainTime_L=0,Train_time_temp; + u1Byte LowTraffic_TrainTime_U=200,LowTraffic_TrainTime_L=0; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u1Byte RxIdleAnt = pDM_SWAT_Table->PreAntenna, TargetAnt, nextAnt=0; + PSTA_INFO_T pEntry=NULL; + //static u1Byte reset_idx; + u4Byte value32; + PADAPTER Adapter = pDM_Odm->Adapter; + u8Byte curTxOkCnt=0, curRxOkCnt=0,TxCntOffset, RxCntOffset; + + if(!pDM_Odm->bLinked) //bLinked==False + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[No Link!!!]\n")); + if(pDM_FatTable->bBecomeLinked == TRUE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set REG 948[9:6]=0x0 \n")); + if(pDM_Odm->SupportICType == ODM_RTL8723B) + ODM_SetBBReg(pDM_Odm, 0x948 , BIT9|BIT8|BIT7|BIT6, 0x0); + + pDM_FatTable->bBecomeLinked = pDM_Odm->bLinked; + } + return; + } + else + { + if(pDM_FatTable->bBecomeLinked ==FALSE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Linked !!!]\n")); + + if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + value32 = ODM_GetBBReg(pDM_Odm, 0x864, BIT5|BIT4|BIT3); + + if (value32==0x0) + ODM_UpdateRxIdleAnt_8723B(pDM_Odm, MAIN_ANT, ANT1_2G, ANT2_2G); + else if (value32==0x1) + ODM_UpdateRxIdleAnt_8723B(pDM_Odm, AUX_ANT, ANT2_2G, ANT1_2G); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("8723B: First link! Force antenna to %s\n",(value32 == 0x0?"MAIN":"AUX") )); + } + + pDM_SWAT_Table->lastTxOkCnt = 0; + pDM_SWAT_Table->lastRxOkCnt =0; + TxCntOffset = *(pDM_Odm->pNumTxBytesUnicast); + RxCntOffset = *(pDM_Odm->pNumRxBytesUnicast); + + pDM_FatTable->bBecomeLinked = pDM_Odm->bLinked; + } + else + { + TxCntOffset = 0; + RxCntOffset = 0; + } + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[%d] { try_flag=(( %d )), Step=(( %d )), Double_chk_flag = (( %d )) }\n", + __LINE__,pDM_SWAT_Table->try_flag,Step,pDM_SWAT_Table->Double_chk_flag)); + + // Handling step mismatch condition. + // Peak step is not finished at last time. Recover the variable and check again. + if( Step != pDM_SWAT_Table->try_flag ) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Step != try_flag] Need to Reset After Link\n")); + ODM_SwAntDivRestAfterLink(pDM_Odm); + } + + if(pDM_SWAT_Table->try_flag == 0xff) + { + pDM_SWAT_Table->try_flag = 0; + pDM_SWAT_Table->Train_time_flag=0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("[set try_flag = 0] Prepare for peak!\n\n")); + return; + } + else//if( try_flag != 0xff ) + { + //1 Normal State (Begin Trying) + if(pDM_SWAT_Table->try_flag == 0) + { + + //---trafic decision--- + curTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast) - pDM_SWAT_Table->lastTxOkCnt - TxCntOffset; + curRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast) - pDM_SWAT_Table->lastRxOkCnt - RxCntOffset; + pDM_SWAT_Table->lastTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast); + pDM_SWAT_Table->lastRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast); + + if (curTxOkCnt > 1875000 || curRxOkCnt > 1875000)//if(PlatformDivision64(curTxOkCnt+curRxOkCnt, 2) > 1875000) ( 1.875M * 8bit ) / 2= 7.5M bits /sec ) + { + pDM_SWAT_Table->TrafficLoad = TRAFFIC_HIGH; + Train_time_temp=pDM_SWAT_Table->Train_time ; + + if(pDM_SWAT_Table->Train_time_flag==3) + { + HighTraffic_TrainTime_L=0xa; + + if(Train_time_temp<=16) + Train_time_temp=HighTraffic_TrainTime_L; + else + Train_time_temp-=16; + + } + else if(pDM_SWAT_Table->Train_time_flag==2) + { + Train_time_temp-=8; + HighTraffic_TrainTime_L=0xf; + } + else if(pDM_SWAT_Table->Train_time_flag==1) + { + Train_time_temp-=4; + HighTraffic_TrainTime_L=0x1e; + } + else if(pDM_SWAT_Table->Train_time_flag==0) + { + Train_time_temp+=8; + HighTraffic_TrainTime_L=0x28; + } + + + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Train_time_temp = ((%d))\n",Train_time_temp)); + + //-- + if(Train_time_temp > HighTraffic_TrainTime_U) + Train_time_temp=HighTraffic_TrainTime_U; + + else if(Train_time_temp < HighTraffic_TrainTime_L) + Train_time_temp=HighTraffic_TrainTime_L; + + pDM_SWAT_Table->Train_time = Train_time_temp; //50ms~10ms + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" Train_time_flag=((%d)) , Train_time=((%d)) \n",pDM_SWAT_Table->Train_time_flag, pDM_SWAT_Table->Train_time)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [HIGH Traffic] \n" )); + } + else if (curTxOkCnt > 125000 || curRxOkCnt > 125000) // ( 0.125M * 8bit ) / 2 = 0.5M bits /sec ) + { + pDM_SWAT_Table->TrafficLoad = TRAFFIC_LOW; + Train_time_temp=pDM_SWAT_Table->Train_time ; + + if(pDM_SWAT_Table->Train_time_flag==3) + { + LowTraffic_TrainTime_L=10; + if(Train_time_temp<50) + Train_time_temp=LowTraffic_TrainTime_L; + else + Train_time_temp-=50; + } + else if(pDM_SWAT_Table->Train_time_flag==2) + { + Train_time_temp-=30; + LowTraffic_TrainTime_L=36; + } + else if(pDM_SWAT_Table->Train_time_flag==1) + { + Train_time_temp-=10; + LowTraffic_TrainTime_L=40; + } + else + Train_time_temp+=10; + + //-- + if(Train_time_temp >= LowTraffic_TrainTime_U) + Train_time_temp=LowTraffic_TrainTime_U; + + else if(Train_time_temp <= LowTraffic_TrainTime_L) + Train_time_temp=LowTraffic_TrainTime_L; + + pDM_SWAT_Table->Train_time = Train_time_temp; //50ms~20ms + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" Train_time_flag=((%d)) , Train_time=((%d)) \n",pDM_SWAT_Table->Train_time_flag, pDM_SWAT_Table->Train_time)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [Low Traffic] \n" )); + } + else + { + pDM_SWAT_Table->TrafficLoad = TRAFFIC_UltraLOW; + pDM_SWAT_Table->Train_time = 0xc8; //200ms + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [Ultra-Low Traffic] \n" )); + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("TxOkCnt=(( %llu )), RxOkCnt=(( %llu )) \n", + curTxOkCnt ,curRxOkCnt )); + + //----------------- + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" Current MinMaxRSSI is ((%d)) \n",pDM_FatTable->MinMaxRSSI)); + + //---reset index--- + if(pDM_SWAT_Table->reset_idx>=reset_period) + { + pDM_FatTable->MinMaxRSSI=0; // + pDM_SWAT_Table->reset_idx=0; + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("reset_idx = (( %d )) \n",pDM_SWAT_Table->reset_idx )); + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("reset_idx=%d\n",pDM_SWAT_Table->reset_idx)); + pDM_SWAT_Table->reset_idx++; + + //---double check flag--- + if(pDM_FatTable->MinMaxRSSI > SWAntDiv_threshold && pDM_SWAT_Table->Double_chk_flag== 0) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" MinMaxRSSI is ((%d)), and > %d \n", + pDM_FatTable->MinMaxRSSI,SWAntDiv_threshold)); + + pDM_SWAT_Table->Double_chk_flag =1; + pDM_SWAT_Table->try_flag = 1; + pDM_SWAT_Table->RSSI_Trying = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" Test the current Ant for (( %d )) ms again \n", pDM_SWAT_Table->Train_time)); + ODM_UpdateRxIdleAnt(pDM_Odm, pDM_FatTable->RxIdleAnt); + ODM_SetTimer(pDM_Odm,&pDM_SWAT_Table->SwAntennaSwitchTimer_8723B, pDM_SWAT_Table->Train_time ); //ms + return; + } + + nextAnt = (pDM_FatTable->RxIdleAnt == MAIN_ANT)? AUX_ANT : MAIN_ANT; + + pDM_SWAT_Table->try_flag = 1; + + if(pDM_SWAT_Table->reset_idx<=1) + pDM_SWAT_Table->RSSI_Trying = 2; + else + pDM_SWAT_Table->RSSI_Trying = 1; + + odm_S0S1_SwAntDivByCtrlFrame(pDM_Odm, SWAW_STEP_PEAK); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("[set try_flag=1] Normal State: Begin Trying!! \n")); + } + + else if(pDM_SWAT_Table->try_flag == 1 && pDM_SWAT_Table->Double_chk_flag== 0) + { + nextAnt = (pDM_FatTable->RxIdleAnt == MAIN_ANT)? AUX_ANT : MAIN_ANT; + pDM_SWAT_Table->RSSI_Trying--; + } + + //1 Decision State + if((pDM_SWAT_Table->try_flag == 1)&&(pDM_SWAT_Table->RSSI_Trying == 0) ) + { + BOOLEAN bByCtrlFrame = FALSE; + u8Byte pkt_cnt_total = 0; + + for (i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pEntry)) + { + //2 Caculate RSSI per Antenna + Main_RSSI = (pDM_FatTable->MainAnt_Cnt[i]!=0)?(pDM_FatTable->MainAnt_Sum[i]/pDM_FatTable->MainAnt_Cnt[i]):0; + Aux_RSSI = (pDM_FatTable->AuxAnt_Cnt[i]!=0)?(pDM_FatTable->AuxAnt_Sum[i]/pDM_FatTable->AuxAnt_Cnt[i]):0; + + if(pDM_FatTable->MainAnt_Cnt[i]<=1 && pDM_FatTable->CCK_counter_main>=1) + Main_RSSI=0; + + if(pDM_FatTable->AuxAnt_Cnt[i]<=1 && pDM_FatTable->CCK_counter_aux>=1) + Aux_RSSI=0; + + TargetAnt = (Main_RSSI==Aux_RSSI)?pDM_SWAT_Table->PreAntenna:((Main_RSSI>=Aux_RSSI)?MAIN_ANT:AUX_ANT); + LocalMaxRSSI = (Main_RSSI>=Aux_RSSI) ? Main_RSSI : Aux_RSSI; + LocalMinRSSI = (Main_RSSI>=Aux_RSSI) ? Aux_RSSI : Main_RSSI; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** CCK_counter_main = (( %d )) , CCK_counter_aux= (( %d )) \n", pDM_FatTable->CCK_counter_main, pDM_FatTable->CCK_counter_aux)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** OFDM_counter_main = (( %d )) , OFDM_counter_aux= (( %d )) \n", pDM_FatTable->OFDM_counter_main, pDM_FatTable->OFDM_counter_aux)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Main_Cnt = (( %d )) , Main_RSSI= (( %d )) \n", pDM_FatTable->MainAnt_Cnt[i], Main_RSSI)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Aux_Cnt = (( %d )) , Aux_RSSI = (( %d )) \n", pDM_FatTable->AuxAnt_Cnt[i] , Aux_RSSI )); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** MAC ID:[ %d ] , TargetAnt = (( %s )) \n", i ,( TargetAnt ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + + //2 Select RX Idle Antenna + + if (LocalMaxRSSI != 0 && LocalMaxRSSI < MinMaxRSSI) + { + RxIdleAnt = TargetAnt; + MinMaxRSSI = LocalMaxRSSI; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** LocalMaxRSSI-LocalMinRSSI = ((%d))\n",(LocalMaxRSSI-LocalMinRSSI))); + + if((LocalMaxRSSI-LocalMinRSSI)>8) + { + if(LocalMinRSSI != 0) + pDM_SWAT_Table->Train_time_flag=3; + else + { + if(MinMaxRSSI > SWAntDiv_threshold) + pDM_SWAT_Table->Train_time_flag=0; + else + pDM_SWAT_Table->Train_time_flag=3; + } + } + else if((LocalMaxRSSI-LocalMinRSSI)>5) + pDM_SWAT_Table->Train_time_flag=2; + else if((LocalMaxRSSI-LocalMinRSSI)>2) + pDM_SWAT_Table->Train_time_flag=1; + else + pDM_SWAT_Table->Train_time_flag=0; + + } + + //2 Select TX Antenna + if(TargetAnt == MAIN_ANT) + pDM_FatTable->antsel_a[i] = ANT1_2G; + else + pDM_FatTable->antsel_a[i] = ANT2_2G; + + } + pDM_FatTable->MainAnt_Sum[i] = 0; + pDM_FatTable->AuxAnt_Sum[i] = 0; + pDM_FatTable->MainAnt_Cnt[i] = 0; + pDM_FatTable->AuxAnt_Cnt[i] = 0; + } + + if(pDM_SWAT_Table->bSWAntDivByCtrlFrame) + { + odm_S0S1_SwAntDivByCtrlFrame(pDM_Odm, SWAW_STEP_DETERMINE); + bByCtrlFrame = TRUE; + } + + pkt_cnt_total = pDM_FatTable->CCK_counter_main + pDM_FatTable->CCK_counter_aux + + pDM_FatTable->OFDM_counter_main + pDM_FatTable->OFDM_counter_aux; + pDM_FatTable->CCK_counter_main=0; + pDM_FatTable->CCK_counter_aux=0; + pDM_FatTable->OFDM_counter_main=0; + pDM_FatTable->OFDM_counter_aux=0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Control frame packet counter = %d, Data frame packet counter = %llu\n", + pDM_SWAT_Table->PktCnt_SWAntDivByCtrlFrame, pkt_cnt_total)); + + if(MinMaxRSSI == 0xff || ((pkt_cnt_total < (pDM_SWAT_Table->PktCnt_SWAntDivByCtrlFrame >> 1)) && pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 2)) + { + MinMaxRSSI = 0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Check RSSI of control frame because MinMaxRSSI == 0xff\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("bByCtrlFrame = %d\n", bByCtrlFrame)); + + if(bByCtrlFrame) + { + Main_RSSI = (pDM_FatTable->MainAnt_CtrlFrame_Cnt!=0)?(pDM_FatTable->MainAnt_CtrlFrame_Sum/pDM_FatTable->MainAnt_CtrlFrame_Cnt):0; + Aux_RSSI = (pDM_FatTable->AuxAnt_CtrlFrame_Cnt!=0)?(pDM_FatTable->AuxAnt_CtrlFrame_Sum/pDM_FatTable->AuxAnt_CtrlFrame_Cnt):0; + + if(pDM_FatTable->MainAnt_CtrlFrame_Cnt<=1 && pDM_FatTable->CCK_CtrlFrame_Cnt_main>=1) + Main_RSSI=0; + + if(pDM_FatTable->AuxAnt_CtrlFrame_Cnt<=1 && pDM_FatTable->CCK_CtrlFrame_Cnt_aux>=1) + Aux_RSSI=0; + + if (Main_RSSI != 0 || Aux_RSSI != 0) + { + RxIdleAnt = (Main_RSSI==Aux_RSSI)?pDM_SWAT_Table->PreAntenna:((Main_RSSI>=Aux_RSSI)?MAIN_ANT:AUX_ANT); + LocalMaxRSSI = (Main_RSSI>=Aux_RSSI) ? Main_RSSI : Aux_RSSI; + LocalMinRSSI = (Main_RSSI>=Aux_RSSI) ? Aux_RSSI : Main_RSSI; + + if((LocalMaxRSSI-LocalMinRSSI)>8) + pDM_SWAT_Table->Train_time_flag=3; + else if((LocalMaxRSSI-LocalMinRSSI)>5) + pDM_SWAT_Table->Train_time_flag=2; + else if((LocalMaxRSSI-LocalMinRSSI)>2) + pDM_SWAT_Table->Train_time_flag=1; + else + pDM_SWAT_Table->Train_time_flag=0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Control frame: Main_RSSI = %d, Aux_RSSI = %d\n", Main_RSSI, Aux_RSSI)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("RxIdleAnt decided by control frame = %s\n", (RxIdleAnt == MAIN_ANT?"MAIN":"AUX"))); + } + } + } + + pDM_FatTable->MinMaxRSSI=MinMaxRSSI; + pDM_SWAT_Table->try_flag = 0; + + if( pDM_SWAT_Table->Double_chk_flag==1) + { + pDM_SWAT_Table->Double_chk_flag=0; + if(pDM_FatTable->MinMaxRSSI > SWAntDiv_threshold) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" [Double check] MinMaxRSSI ((%d)) > %d again!! \n", + pDM_FatTable->MinMaxRSSI,SWAntDiv_threshold)); + + ODM_UpdateRxIdleAnt(pDM_Odm, RxIdleAnt); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("[reset try_flag = 0] Training accomplished !!!] \n\n\n")); + return; + } + else + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" [Double check] MinMaxRSSI ((%d)) <= %d !! \n", + pDM_FatTable->MinMaxRSSI,SWAntDiv_threshold)); + + nextAnt = (pDM_FatTable->RxIdleAnt == MAIN_ANT)? AUX_ANT : MAIN_ANT; + pDM_SWAT_Table->try_flag = 0; + pDM_SWAT_Table->reset_idx=reset_period; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("[set try_flag=0] Normal State: Need to tryg again!! \n\n\n")); + return; + } + } + else + { + if(pDM_FatTable->MinMaxRSSI < SWAntDiv_threshold) + pDM_SWAT_Table->reset_idx=reset_period; + + pDM_SWAT_Table->PreAntenna =RxIdleAnt; + ODM_UpdateRxIdleAnt(pDM_Odm, RxIdleAnt ); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("[reset try_flag = 0] Training accomplished !!!] \n\n\n")); + return; + } + + } + + } + + //1 4.Change TRX antenna + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("RSSI_Trying = (( %d )), Ant: (( %s )) >>> (( %s )) \n", + pDM_SWAT_Table->RSSI_Trying, (pDM_FatTable->RxIdleAnt == MAIN_ANT?"MAIN":"AUX"),(nextAnt == MAIN_ANT?"MAIN":"AUX"))); + + ODM_UpdateRxIdleAnt(pDM_Odm, nextAnt); + + //1 5.Reset Statistics + + pDM_FatTable->RxIdleAnt = nextAnt; + + //1 6.Set next timer (Trying State) + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" Test ((%s)) Ant for (( %d )) ms \n", (nextAnt == MAIN_ANT?"MAIN":"AUX"), pDM_SWAT_Table->Train_time)); + ODM_SetTimer(pDM_Odm,&pDM_SWAT_Table->SwAntennaSwitchTimer_8723B, pDM_SWAT_Table->Train_time ); //ms +} + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_SW_AntDiv_Callback( + PRT_TIMER pTimer +) +{ + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + pSWAT_T pDM_SWAT_Table = &pHalData->DM_OutSrc.DM_SWAT_Table; + + #if DEV_BUS_TYPE==RT_PCI_INTERFACE + #if USE_WORKITEM + ODM_ScheduleWorkItem(&pDM_SWAT_Table->SwAntennaSwitchWorkitem_8723B); + #else + { + //DbgPrint("SW_antdiv_Callback"); + odm_S0S1_SwAntDiv(&pHalData->DM_OutSrc, SWAW_STEP_DETERMINE); + } + #endif + #else + ODM_ScheduleWorkItem(&pDM_SWAT_Table->SwAntennaSwitchWorkitem_8723B); + #endif +} +VOID +ODM_SW_AntDiv_WorkitemCallback( + IN PVOID pContext + ) +{ + PADAPTER pAdapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + //DbgPrint("SW_antdiv_Workitem_Callback"); + odm_S0S1_SwAntDiv(&pHalData->DM_OutSrc, SWAW_STEP_DETERMINE); +} + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + +VOID +ODM_SW_AntDiv_WorkitemCallback( + IN PVOID pContext + ) +{ + PADAPTER pAdapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + //DbgPrint("SW_antdiv_Workitem_Callback"); + odm_S0S1_SwAntDiv(&pHalData->odmpriv, SWAW_STEP_DETERMINE); +} + +VOID +ODM_SW_AntDiv_Callback(void *FunctionContext) +{ + PDM_ODM_T pDM_Odm= (PDM_ODM_T)FunctionContext; + PADAPTER padapter = pDM_Odm->Adapter; + + + if(padapter->net_closed == _TRUE) + return; + +#if 0 // Can't do I/O in timer callback + odm_S0S1_SwAntDiv(pDM_Odm, SWAW_STEP_DETERMINE); +#else + rtw_run_in_thread_cmd(padapter, ODM_SW_AntDiv_WorkitemCallback, padapter); +#endif +} + +#endif + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +odm_S0S1_SwAntDivByCtrlFrame( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Step + ) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + switch(Step) + { + case SWAW_STEP_PEAK: + pDM_SWAT_Table->PktCnt_SWAntDivByCtrlFrame = 0; + pDM_SWAT_Table->bSWAntDivByCtrlFrame = TRUE; + pDM_FatTable->MainAnt_CtrlFrame_Cnt = 0; + pDM_FatTable->AuxAnt_CtrlFrame_Cnt = 0; + pDM_FatTable->MainAnt_CtrlFrame_Sum = 0; + pDM_FatTable->AuxAnt_CtrlFrame_Sum = 0; + pDM_FatTable->CCK_CtrlFrame_Cnt_main = 0; + pDM_FatTable->CCK_CtrlFrame_Cnt_aux = 0; + pDM_FatTable->OFDM_CtrlFrame_Cnt_main = 0; + pDM_FatTable->OFDM_CtrlFrame_Cnt_aux = 0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("odm_S0S1_SwAntDivForAPMode(): Start peak and reset counter\n")); + break; + case SWAW_STEP_DETERMINE: + pDM_SWAT_Table->bSWAntDivByCtrlFrame = FALSE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("odm_S0S1_SwAntDivForAPMode(): Stop peak\n")); + break; + default: + pDM_SWAT_Table->bSWAntDivByCtrlFrame = FALSE; + break; + } +} + +VOID +odm_AntselStatisticsOfCtrlFrame( + IN PDM_ODM_T pDM_Odm, + IN u1Byte antsel_tr_mux, + IN u4Byte RxPWDBAll +) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + if(antsel_tr_mux == ANT1_2G) + { + pDM_FatTable->MainAnt_CtrlFrame_Sum+=RxPWDBAll; + pDM_FatTable->MainAnt_CtrlFrame_Cnt++; + } + else + { + pDM_FatTable->AuxAnt_CtrlFrame_Sum+=RxPWDBAll; + pDM_FatTable->AuxAnt_CtrlFrame_Cnt++; + } +} + +VOID +odm_S0S1_SwAntDivByCtrlFrame_ProcessRSSI( + IN PDM_ODM_T pDM_Odm, + IN PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + BOOLEAN isCCKrate; + + if(!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) + return; + + if(pDM_Odm->AntDivType != S0S1_SW_ANTDIV) + return; + + // In try state + if(!pDM_SWAT_Table->bSWAntDivByCtrlFrame) + return; + + // No HW error and match receiver address + if(!pPktinfo->bToSelf) + return; + + pDM_SWAT_Table->PktCnt_SWAntDivByCtrlFrame++; + isCCKrate = ((pPktinfo->DataRate >= DESC_RATE1M ) && (pPktinfo->DataRate <= DESC_RATE11M ))?TRUE :FALSE; + + if(isCCKrate) + { + pDM_FatTable->antsel_rx_keep_0 = (pDM_FatTable->RxIdleAnt == MAIN_ANT) ? ANT1_2G : ANT2_2G; + + if(pDM_FatTable->antsel_rx_keep_0==ANT1_2G) + pDM_FatTable->CCK_CtrlFrame_Cnt_main++; + else + pDM_FatTable->CCK_CtrlFrame_Cnt_aux++; + + odm_AntselStatisticsOfCtrlFrame(pDM_Odm, pDM_FatTable->antsel_rx_keep_0, pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]); + } + else + { + if(pDM_FatTable->antsel_rx_keep_0==ANT1_2G) + pDM_FatTable->OFDM_CtrlFrame_Cnt_main++; + else + pDM_FatTable->OFDM_CtrlFrame_Cnt_aux++; + + odm_AntselStatisticsOfCtrlFrame(pDM_Odm, pDM_FatTable->antsel_rx_keep_0, pPhyInfo->RxPWDBAll); + } +} +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + + +#endif //#if (RTL8723B_SUPPORT == 1) + + +#if(RTL8188E_SUPPORT == 1 || RTL8192E_SUPPORT == 1) +#if (!(DM_ODM_SUPPORT_TYPE == ODM_CE)) +VOID +odm_SetNextMACAddrTarget( + IN PDM_ODM_T pDM_Odm +) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + PSTA_INFO_T pEntry; + //u1Byte Bssid[6]; + u4Byte value32, i; + + // + //2012.03.26 LukeLee: The MAC address is changed according to MACID in turn + // + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_SetNextMACAddrTarget() ==>\n")); + if(pDM_Odm->bLinked) + { + for (i=0; iTrainIdx+1) == ODM_ASSOCIATE_ENTRY_NUM) + pDM_FatTable->TrainIdx = 0; + else + pDM_FatTable->TrainIdx++; + + pEntry = pDM_Odm->pODM_StaInfo[pDM_FatTable->TrainIdx]; + if(IS_STA_VALID(pEntry)) + { + //Match MAC ADDR +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + value32 = (pEntry->hwaddr[5]<<8)|pEntry->hwaddr[4]; +#else + value32 = (pEntry->MacAddr[5]<<8)|pEntry->MacAddr[4]; +#endif + ODM_SetMACReg(pDM_Odm, 0x7b4, 0xFFFF, value32); +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + value32 = (pEntry->hwaddr[3]<<24)|(pEntry->hwaddr[2]<<16) |(pEntry->hwaddr[1]<<8) |pEntry->hwaddr[0]; +#else + value32 = (pEntry->MacAddr[3]<<24)|(pEntry->MacAddr[2]<<16) |(pEntry->MacAddr[1]<<8) |pEntry->MacAddr[0]; +#endif + ODM_SetMACReg(pDM_Odm, 0x7b0, bMaskDWord, value32); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_FatTable->TrainIdx=%lu\n",pDM_FatTable->TrainIdx)); +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Training MAC Addr = %x:%x:%x:%x:%x:%x\n", + pEntry->hwaddr[5],pEntry->hwaddr[4],pEntry->hwaddr[3],pEntry->hwaddr[2],pEntry->hwaddr[1],pEntry->hwaddr[0])); +#else + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Training MAC Addr = %x:%x:%x:%x:%x:%x\n", + pEntry->MacAddr[5],pEntry->MacAddr[4],pEntry->MacAddr[3],pEntry->MacAddr[2],pEntry->MacAddr[1],pEntry->MacAddr[0])); +#endif + + break; + } + } + + } + +#if 0 + // + //2012.03.26 LukeLee: This should be removed later, the MAC address is changed according to MACID in turn + // + #if( DM_ODM_SUPPORT_TYPE & ODM_WIN) + { + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + for (i=0; i<6; i++) + { + Bssid[i] = pMgntInfo->Bssid[i]; + //DbgPrint("Bssid[%d]=%x\n", i, Bssid[i]); + } + } + #endif + + //odm_SetNextMACAddrTarget(pDM_Odm); + + //1 Select MAC Address Filter + for (i=0; i<6; i++) + { + if(Bssid[i] != pDM_FatTable->Bssid[i]) + { + bMatchBSSID = FALSE; + break; + } + } + if(bMatchBSSID == FALSE) + { + //Match MAC ADDR + value32 = (Bssid[5]<<8)|Bssid[4]; + ODM_SetMACReg(pDM_Odm, 0x7b4, 0xFFFF, value32); + value32 = (Bssid[3]<<24)|(Bssid[2]<<16) |(Bssid[1]<<8) |Bssid[0]; + ODM_SetMACReg(pDM_Odm, 0x7b0, bMaskDWord, value32); + } + + return bMatchBSSID; +#endif + +} + +VOID +odm_FastAntTraining( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i, MaxRSSI=0; + u1Byte TargetAnt=2; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + BOOLEAN bPktFilterMacth = FALSE; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("==>odm_FastAntTraining()\n")); + + //1 TRAINING STATE + if(pDM_FatTable->FAT_State == FAT_TRAINING_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Enter FAT_TRAINING_STATE\n")); + //2 Caculate RSSI per Antenna + for (i=0; i<7; i++) + { + if(pDM_FatTable->antRSSIcnt[i] == 0) + pDM_FatTable->antAveRSSI[i] = 0; + else + { + pDM_FatTable->antAveRSSI[i] = pDM_FatTable->antSumRSSI[i] /pDM_FatTable->antRSSIcnt[i]; + bPktFilterMacth = TRUE; + } + if(pDM_FatTable->antAveRSSI[i] > MaxRSSI) + { + MaxRSSI = pDM_FatTable->antAveRSSI[i]; + TargetAnt = (u1Byte) i; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_FatTable->antAveRSSI[%lu] = %lu, pDM_FatTable->antRSSIcnt[%lu] = %lu\n", + i, pDM_FatTable->antAveRSSI[i], i, pDM_FatTable->antRSSIcnt[i])); + } + + //2 Select TRX Antenna + if(bPktFilterMacth == FALSE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("None Packet is matched\n")); + + ODM_SetBBReg(pDM_Odm, 0xe08 , BIT16, 0); //RegE08[16]=1'b0 //disable fast training + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, 0); //RegC50[7]=1'b0 //disable HW AntDiv + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("TargetAnt=%d, MaxRSSI=%lu\n",TargetAnt,MaxRSSI)); + + ODM_SetBBReg(pDM_Odm, 0xe08 , BIT16, 0); //RegE08[16]=1'b0 //disable fast training + //ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, 0); //RegC50[7]=1'b0 //disable HW AntDiv + ODM_SetBBReg(pDM_Odm, 0x864 , BIT8|BIT7|BIT6, TargetAnt); //Default RX is Omni, Optional RX is the best decision by FAT + //ODM_SetBBReg(pDM_Odm, 0x860 , BIT14|BIT13|BIT12, TargetAnt); //Default TX + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, 1); //Reg80c[21]=1'b1 //from TX Info + +#if 0 + pEntry = pDM_Odm->pODM_StaInfo[pDM_FatTable->TrainIdx]; + + if(IS_STA_VALID(pEntry)) + { + pEntry->antsel_a = TargetAnt&BIT0; + pEntry->antsel_b = (TargetAnt&BIT1)>>1; + pEntry->antsel_c = (TargetAnt&BIT2)>>2; + } +#else + pDM_FatTable->antsel_a[pDM_FatTable->TrainIdx] = TargetAnt&BIT0; + pDM_FatTable->antsel_b[pDM_FatTable->TrainIdx] = (TargetAnt&BIT1)>>1; + pDM_FatTable->antsel_c[pDM_FatTable->TrainIdx] = (TargetAnt&BIT2)>>2; +#endif + + + if(TargetAnt == 0) + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, 0); //RegC50[7]=1'b0 //disable HW AntDiv + + } + + //2 Reset Counter + for(i=0; i<7; i++) + { + pDM_FatTable->antSumRSSI[i] = 0; + pDM_FatTable->antRSSIcnt[i] = 0; + } + + pDM_FatTable->FAT_State = FAT_NORMAL_STATE; + return; + } + + //1 NORMAL STATE + if(pDM_FatTable->FAT_State == FAT_NORMAL_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Enter FAT_NORMAL_STATE\n")); + + odm_SetNextMACAddrTarget(pDM_Odm); + +#if 0 + pEntry = pDM_Odm->pODM_StaInfo[pDM_FatTable->TrainIdx]; + if(IS_STA_VALID(pEntry)) + { + pEntry->antsel_a = TargetAnt&BIT0; + pEntry->antsel_b = (TargetAnt&BIT1)>>1; + pEntry->antsel_c = (TargetAnt&BIT2)>>2; + } +#endif + + //2 Prepare Training + pDM_FatTable->FAT_State = FAT_TRAINING_STATE; + ODM_SetBBReg(pDM_Odm, 0xe08 , BIT16, 1); //RegE08[16]=1'b1 //enable fast training + ODM_SetBBReg(pDM_Odm, 0xc50 , BIT7, 1); //RegC50[7]=1'b1 //enable HW AntDiv + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Start FAT_TRAINING_STATE\n")); + ODM_SetTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer, 500 ); //ms + + } + +} + +VOID +odm_FastAntTrainingCallback( + IN PDM_ODM_T pDM_Odm +) +{ + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PADAPTER padapter = pDM_Odm->Adapter; + if(padapter->net_closed == _TRUE) + return; + //if(*pDM_Odm->pbNet_closed == TRUE) + // return; +#endif + +#if USE_WORKITEM + ODM_ScheduleWorkItem(&pDM_Odm->FastAntTrainingWorkitem); +#else + odm_FastAntTraining(pDM_Odm); +#endif +} + +VOID +odm_FastAntTrainingWorkItemCallback( + IN PDM_ODM_T pDM_Odm +) +{ + odm_FastAntTraining(pDM_Odm); +} +#endif + +#endif + +VOID +ODM_AntDivReset( + IN PDM_ODM_T pDM_Odm + ) +{ + //2 [--8723B---] +#if (RTL8723B_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8723B) + odm_S0S1_SWAntDiv_Reset_8723B(pDM_Odm); +#endif +} + +VOID +ODM_AntDivInit( + IN PDM_ODM_T pDM_Odm + ) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + + + if(!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] Not Support Antenna Diversity Function\n")); + return; + } + //--- +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + if(pDM_FatTable->AntDiv_2G_5G == ODM_ANTDIV_2G) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[2G AntDiv Init]: Only Support 2G Antenna Diversity Function\n")); + if(!(pDM_Odm->SupportICType & ODM_ANTDIV_2G_SUPPORT_IC)) + return; + } + else if(pDM_FatTable->AntDiv_2G_5G == ODM_ANTDIV_5G) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[5G AntDiv Init]: Only Support 5G Antenna Diversity Function\n")); + if(!(pDM_Odm->SupportICType & ODM_ANTDIV_5G_SUPPORT_IC)) + return; + } + else if(pDM_FatTable->AntDiv_2G_5G == (ODM_ANTDIV_2G|ODM_ANTDIV_5G)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[2G & 5G AntDiv Init]:Support Both 2G & 5G Antenna Diversity Function\n")); + } + + pDM_Odm->antdiv_rssi=0; + +#endif + //--- + + //2 [--General---] + pDM_Odm->antdiv_period=0; + pDM_Odm->antdiv_select=0; + pDM_SWAT_Table->Ant5G = MAIN_ANT; + pDM_SWAT_Table->Ant2G = MAIN_ANT; + pDM_FatTable->CCK_counter_main=0; + pDM_FatTable->CCK_counter_aux=0; + pDM_FatTable->OFDM_counter_main=0; + pDM_FatTable->OFDM_counter_aux=0; + + //3 [Set MAIN_ANT as default antenna if Auto-Ant enable] + if (pDM_Odm->antdiv_select==1) + pDM_Odm->AntType = ODM_FIX_MAIN_ANT; + else if (pDM_Odm->antdiv_select==2) + pDM_Odm->AntType = ODM_FIX_AUX_ANT; + else if(pDM_Odm->antdiv_select==0) + pDM_Odm->AntType = ODM_AUTO_ANT; + + if(pDM_Odm->AntType == ODM_AUTO_ANT) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + } + else + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + + if(pDM_Odm->AntType == ODM_FIX_MAIN_ANT) + { + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + return; + } + else if(pDM_Odm->AntType == ODM_FIX_AUX_ANT) + { + ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT); + return; + } + } + //--- + if(pDM_Odm->AntDivType != CGCS_RX_HW_ANTDIV) + { + if(pDM_Odm->SupportICType & ODM_N_ANTDIV_SUPPORT) + { + #if TX_BY_REG + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, 0); //Reg80c[21]=1'b0 //from Reg + #else + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, 1); + #endif + } + else if(pDM_Odm->SupportICType & ODM_AC_ANTDIV_SUPPORT) + { + #if TX_BY_REG + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, 0); + #else + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, 1); + #endif + } + } + + //2 [--88E---] + if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + #if (RTL8188E_SUPPORT == 1) + //pDM_Odm->AntDivType = CGCS_RX_HW_ANTDIV; + //pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + //pDM_Odm->AntDivType = CG_TRX_SMART_ANTDIV; + + if( (pDM_Odm->AntDivType != CGCS_RX_HW_ANTDIV) && (pDM_Odm->AntDivType != CG_TRX_HW_ANTDIV) && (pDM_Odm->AntDivType != CG_TRX_SMART_ANTDIV)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] 88E Not Supprrt This AntDiv Type\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + return; + } + + if(pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) + odm_RX_HWAntDiv_Init_88E(pDM_Odm); + else if(pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) + odm_TRX_HWAntDiv_Init_88E(pDM_Odm); + else if(pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV) + odm_Smart_HWAntDiv_Init_88E(pDM_Odm); + #endif + } + + //2 [--92E---] + #if (RTL8192E_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + //pDM_Odm->AntDivType = CGCS_RX_HW_ANTDIV; + //pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + //pDM_Odm->AntDivType = CG_TRX_SMART_ANTDIV; + + if( (pDM_Odm->AntDivType != CGCS_RX_HW_ANTDIV) && (pDM_Odm->AntDivType != CG_TRX_HW_ANTDIV) && (pDM_Odm->AntDivType != CG_TRX_SMART_ANTDIV)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] 8192E Not Supprrt This AntDiv Type\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + return; + } + + if(pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) + odm_RX_HWAntDiv_Init_92E(pDM_Odm); + else if(pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) + odm_TRX_HWAntDiv_Init_92E(pDM_Odm); + else if(pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV) + odm_Smart_HWAntDiv_Init_92E(pDM_Odm); + + } + #endif + + //2 [--8723B---] + #if (RTL8723B_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + //pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + //pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + + if(pDM_Odm->AntDivType != S0S1_SW_ANTDIV && pDM_Odm->AntDivType != CG_TRX_HW_ANTDIV) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] 8723B Not Supprrt This AntDiv Type\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + return; + } + + if( pDM_Odm->AntDivType==S0S1_SW_ANTDIV) + odm_S0S1_SWAntDiv_Init_8723B(pDM_Odm); + else if(pDM_Odm->AntDivType==CG_TRX_HW_ANTDIV) + odm_TRX_HWAntDiv_Init_8723B(pDM_Odm); + } + #endif + + //2 [--8811A 8821A---] + #if (RTL8821A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8821) + { + //pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + + if( pDM_Odm->AntDivType != CG_TRX_HW_ANTDIV && pDM_Odm->AntDivType != S0S1_SW_ANTDIV) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] 8821A & 8811A Not Supprrt This AntDiv Type\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + return; + } + if(pDM_Odm->AntDivType==CG_TRX_HW_ANTDIV) + odm_TRX_HWAntDiv_Init_8821A(pDM_Odm); + else if( pDM_Odm->AntDivType==S0S1_SW_ANTDIV) + odm_S0S1_SWAntDiv_Init_8821A(pDM_Odm); + } + #endif + + //2 [--8881A---] + #if (RTL8881A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8881A) + { + //pDM_Odm->AntDivType = CGCS_RX_HW_ANTDIV; + //pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + + if(pDM_Odm->AntDivType != CGCS_RX_HW_ANTDIV && pDM_Odm->AntDivType != CG_TRX_HW_ANTDIV) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] 8881A Not Supprrt This AntDiv Type\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + return; + } + if(pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) + odm_RX_HWAntDiv_Init_8881A(pDM_Odm); + else if(pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) + odm_TRX_HWAntDiv_Init_8881A(pDM_Odm); + } + #endif + + //2 [--8812---] + #if (RTL8812A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8812) + { + //pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + + if( pDM_Odm->AntDivType != CG_TRX_HW_ANTDIV) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] 8812A Not Supprrt This AntDiv Type\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + return; + } + odm_TRX_HWAntDiv_Init_8812A(pDM_Odm); + } + #endif + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("*** SupportICType=[%lu] \n",pDM_Odm->SupportICType)); + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("*** AntDiv SupportAbility=[%lu] \n",(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)>>6)); + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("*** AntDiv Type=[%d] \n",pDM_Odm->AntDivType)); + +} + +VOID +ODM_AntDiv( + IN PDM_ODM_T pDM_Odm +) +{ + PADAPTER pAdapter = pDM_Odm->Adapter; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + +//#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + if(*pDM_Odm->pBandType == ODM_BAND_5G ) + { + if(pDM_FatTable->idx_AntDiv_counter_5G < pDM_Odm->antdiv_period ) + { + pDM_FatTable->idx_AntDiv_counter_5G++; + return; + } + else + pDM_FatTable->idx_AntDiv_counter_5G=0; + } + else if(*pDM_Odm->pBandType == ODM_BAND_2_4G ) + { + if(pDM_FatTable->idx_AntDiv_counter_2G < pDM_Odm->antdiv_period ) + { + pDM_FatTable->idx_AntDiv_counter_2G++; + return; + } + else + pDM_FatTable->idx_AntDiv_counter_2G=0; + } +//#endif + //---------- + if(!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[Return!!!] Not Support Antenna Diversity Function\n")); + return; + } + + //---------- +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if(pAdapter->MgntInfo.AntennaTest) + return; + + { + #if (BEAMFORMING_SUPPORT == 1) + BEAMFORMING_CAP BeamformCap = (pDM_Odm->BeamformingInfo.BeamformCap); + + if( BeamformCap & BEAMFORMEE_CAP ) // BFmee On && Div On -> Div Off + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[ AntDiv : OFF ] BFmee ==1 \n")); + if(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + return; + } + } + else // BFmee Off && Div Off -> Div On + #endif + { + if(!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) && pDM_Odm->bLinked) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[ AntDiv : ON ] BFmee ==0 \n")); + if((pDM_Odm->AntDivType!=S0S1_SW_ANTDIV) ) + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); + + pDM_Odm->SupportAbility |= (ODM_BB_ANT_DIV); + } + } + } +#endif + + //---------- +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + if(pDM_FatTable->AntDiv_2G_5G == ODM_ANTDIV_2G) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[ 2G AntDiv Running ]\n")); + if(!(pDM_Odm->SupportICType & ODM_ANTDIV_2G_SUPPORT_IC)) + return; + } + else if(pDM_FatTable->AntDiv_2G_5G == ODM_ANTDIV_5G) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[ 5G AntDiv Running ]\n")); + if(!(pDM_Odm->SupportICType & ODM_ANTDIV_5G_SUPPORT_IC)) + return; + } + else if(pDM_FatTable->AntDiv_2G_5G == (ODM_ANTDIV_2G|ODM_ANTDIV_5G)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("[ 2G & 5G AntDiv Running ]\n")); + } +#endif + + //---------- + + if (pDM_Odm->antdiv_select==1) + pDM_Odm->AntType = ODM_FIX_MAIN_ANT; + else if (pDM_Odm->antdiv_select==2) + pDM_Odm->AntType = ODM_FIX_AUX_ANT; + else if (pDM_Odm->antdiv_select==0) + pDM_Odm->AntType = ODM_AUTO_ANT; + + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("AntType= (( %d )) , pre_AntType= (( %d )) \n",pDM_Odm->AntType,pDM_Odm->pre_AntType)); + + if(pDM_Odm->AntType != ODM_AUTO_ANT) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Fix Antenna at (( %s ))\n",(pDM_Odm->AntType == ODM_FIX_MAIN_ANT)?"MAIN":"AUX")); + + if(pDM_Odm->AntType != pDM_Odm->pre_AntType) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + + if(pDM_Odm->SupportICType & ODM_N_ANTDIV_SUPPORT) + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, 0); + else if(pDM_Odm->SupportICType & ODM_AC_ANTDIV_SUPPORT) + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, 0); + + if(pDM_Odm->AntType == ODM_FIX_MAIN_ANT) + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + else if(pDM_Odm->AntType == ODM_FIX_AUX_ANT) + ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT); + } + pDM_Odm->pre_AntType=pDM_Odm->AntType; + return; + } + else + { + if(pDM_Odm->AntType != pDM_Odm->pre_AntType) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); + if(pDM_Odm->SupportICType & ODM_N_ANTDIV_SUPPORT) + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, 1); + else if(pDM_Odm->SupportICType & ODM_AC_ANTDIV_SUPPORT) + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, 1); + } + pDM_Odm->pre_AntType=pDM_Odm->AntType; + } + + + //3 ----------------------------------------------------------------------------------------------------------- + //2 [--88E---] + if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + #if (RTL8188E_SUPPORT == 1) + if(pDM_Odm->AntDivType==CG_TRX_HW_ANTDIV ||pDM_Odm->AntDivType==CGCS_RX_HW_ANTDIV) + odm_HW_AntDiv(pDM_Odm); + #if (!(DM_ODM_SUPPORT_TYPE == ODM_CE)) + else if (pDM_Odm->AntDivType==CG_TRX_SMART_ANTDIV) + odm_FastAntTraining(pDM_Odm); + #endif + #endif + } + //2 [--92E---] + #if (RTL8192E_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + if(pDM_Odm->AntDivType==CGCS_RX_HW_ANTDIV) + odm_HW_AntDiv(pDM_Odm); + #if (!(DM_ODM_SUPPORT_TYPE == ODM_CE)) + else if (pDM_Odm->AntDivType==CG_TRX_SMART_ANTDIV) + odm_FastAntTraining(pDM_Odm); + #endif + } + #endif + + #if (RTL8723B_SUPPORT == 1) + //2 [--8723B---] + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + if (pDM_Odm->AntDivType==S0S1_SW_ANTDIV) + odm_S0S1_SwAntDiv(pDM_Odm, SWAW_STEP_PEAK); + else if (pDM_Odm->AntDivType==CG_TRX_HW_ANTDIV) + odm_HW_AntDiv(pDM_Odm); + } + #endif + + //2 [--8821A---] + #if (RTL8821A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8821) + { + if(!pDM_Odm->bBtEnabled) //BT disabled + { + if(pDM_Odm->AntDivType == S0S1_SW_ANTDIV) + { + pDM_Odm->AntDivType=CG_TRX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,(" [S0S1_SW_ANTDIV] -> [CG_TRX_HW_ANTDIV]\n")); + //ODM_SetBBReg(pDM_Odm, 0x8D4 , BIT24, 1); + if(pDM_FatTable->bBecomeLinked ==TRUE) + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); + } + } + else //BT enabled + { + if(pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) + { + pDM_Odm->AntDivType=S0S1_SW_ANTDIV; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,(" [CG_TRX_HW_ANTDIV] -> [S0S1_SW_ANTDIV]\n")); + //ODM_SetBBReg(pDM_Odm, 0x8D4 , BIT24, 0); + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + } + } + + if (pDM_Odm->AntDivType==S0S1_SW_ANTDIV) + odm_S0S1_SwAntDiv(pDM_Odm, SWAW_STEP_PEAK); + else if (pDM_Odm->AntDivType==CG_TRX_HW_ANTDIV) + odm_HW_AntDiv(pDM_Odm); + } + #endif + //2 [--8881A---] + #if (RTL8881A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8881A) + odm_HW_AntDiv(pDM_Odm); + #endif + //2 [--8812A---] + #if (RTL8812A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8812) + odm_HW_AntDiv(pDM_Odm); + #endif +} + + +VOID +odm_AntselStatistics( + IN PDM_ODM_T pDM_Odm, + IN u1Byte antsel_tr_mux, + IN u4Byte MacId, + IN u4Byte RxPWDBAll +) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + if(antsel_tr_mux == ANT1_2G) + { + pDM_FatTable->MainAnt_Sum[MacId]+=RxPWDBAll; + pDM_FatTable->MainAnt_Cnt[MacId]++; + } + else + { + pDM_FatTable->AuxAnt_Sum[MacId]+=RxPWDBAll; + pDM_FatTable->AuxAnt_Cnt[MacId]++; + } +} + + +VOID +ODM_Process_RSSIForAntDiv( + IN OUT PDM_ODM_T pDM_Odm, + IN PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ +u1Byte isCCKrate=0,CCKMaxRate=DESC_RATE11M; +pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + u4Byte RxPower_Ant0, RxPower_Ant1; +#else + u1Byte RxPower_Ant0, RxPower_Ant1; +#endif + + if(pDM_Odm->SupportICType & ODM_N_ANTDIV_SUPPORT) + CCKMaxRate=DESC_RATE11M; + else if(pDM_Odm->SupportICType & ODM_AC_ANTDIV_SUPPORT) + CCKMaxRate=DESC_RATE11M; + isCCKrate = (pPktinfo->DataRate <= CCKMaxRate)?TRUE:FALSE; + +#if ((RTL8192C_SUPPORT == 1) ||(RTL8192D_SUPPORT == 1)) + if(pDM_Odm->SupportICType & ODM_RTL8192C|ODM_RTL8192D) + { + if(pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) + { + //if(pPktinfo->bPacketBeacon) + //{ + // DbgPrint("This is beacon, isCCKrate=%d\n", isCCKrate); + //} + ODM_AntselStatistics_88C(pDM_Odm, pPktinfo->StationID, pPhyInfo->RxPWDBAll, isCCKrate); + } + } +#endif + + if( (pDM_Odm->SupportICType == ODM_RTL8192E||pDM_Odm->SupportICType == ODM_RTL8812) && (pPktinfo->DataRate > CCKMaxRate) ) + { + RxPower_Ant0 = pPhyInfo->RxMIMOSignalStrength[0]; + RxPower_Ant1= pPhyInfo->RxMIMOSignalStrength[1]; + } + else + RxPower_Ant0=pPhyInfo->RxPWDBAll; + + if(pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV) + { + if( (pDM_Odm->SupportICType & ODM_SMART_ANT_SUPPORT) && pPktinfo->bPacketToSelf && pDM_FatTable->FAT_State == FAT_TRAINING_STATE )//(pPktinfo->bPacketMatchBSSID && (!pPktinfo->bPacketBeacon)) + { + u1Byte antsel_tr_mux; + antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2<<2) |(pDM_FatTable->antsel_rx_keep_1 <<1) |pDM_FatTable->antsel_rx_keep_0; + pDM_FatTable->antSumRSSI[antsel_tr_mux] += RxPower_Ant0; + pDM_FatTable->antRSSIcnt[antsel_tr_mux]++; + } + } + else //AntDivType != CG_TRX_SMART_ANTDIV + { + if( ( pDM_Odm->SupportICType & ODM_ANTDIV_SUPPORT ) && (pPktinfo->bPacketToSelf || pPktinfo->bPacketMatchBSSID) ) + { + if(pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E) + odm_AntselStatistics(pDM_Odm, pDM_FatTable->antsel_rx_keep_0, pPktinfo->StationID,RxPower_Ant0); + else// SupportICType == ODM_RTL8821 and ODM_RTL8723B and ODM_RTL8812) + { + if(isCCKrate && (pDM_Odm->AntDivType == S0S1_SW_ANTDIV)) + { + pDM_FatTable->antsel_rx_keep_0 = (pDM_FatTable->RxIdleAnt == MAIN_ANT) ? ANT1_2G : ANT2_2G; + + + if(pDM_FatTable->antsel_rx_keep_0==ANT1_2G) + pDM_FatTable->CCK_counter_main++; + else// if(pDM_FatTable->antsel_rx_keep_0==ANT2_2G) + pDM_FatTable->CCK_counter_aux++; + + odm_AntselStatistics(pDM_Odm, pDM_FatTable->antsel_rx_keep_0, pPktinfo->StationID, RxPower_Ant0); + } + else + { + if(pDM_FatTable->antsel_rx_keep_0==ANT1_2G) + pDM_FatTable->OFDM_counter_main++; + else// if(pDM_FatTable->antsel_rx_keep_0==ANT2_2G) + pDM_FatTable->OFDM_counter_aux++; + odm_AntselStatistics(pDM_Odm, pDM_FatTable->antsel_rx_keep_0, pPktinfo->StationID, RxPower_Ant0); + } + } + } + } + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("isCCKrate=%d, PWDB_ALL=%d\n",isCCKrate, pPhyInfo->RxPWDBAll)); + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("antsel_tr_mux=3'b%d%d%d\n",pDM_FatTable->antsel_rx_keep_2, pDM_FatTable->antsel_rx_keep_1, pDM_FatTable->antsel_rx_keep_0)); +} + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +ODM_SetTxAntByTxInfo( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte pDesc, + IN u1Byte macId +) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + if(!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) + return; + + if(pDM_Odm->AntDivType==CGCS_RX_HW_ANTDIV) + return; + + + if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + #if (RTL8723B_SUPPORT == 1) + SET_TX_DESC_ANTSEL_A_8723B(pDesc, pDM_FatTable->antsel_a[macId]); + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[8723B] SetTxAntByTxInfo_WIN: MacID=%d, antsel_tr_mux=3'b%d%d%d\n", + //macId, pDM_FatTable->antsel_c[macId], pDM_FatTable->antsel_b[macId], pDM_FatTable->antsel_a[macId])); + #endif + } + else if(pDM_Odm->SupportICType == ODM_RTL8821) + { + #if (RTL8821A_SUPPORT == 1) + SET_TX_DESC_ANTSEL_A_8812(pDesc, pDM_FatTable->antsel_a[macId]); + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[8821A] SetTxAntByTxInfo_WIN: MacID=%d, antsel_tr_mux=3'b%d%d%d\n", + //macId, pDM_FatTable->antsel_c[macId], pDM_FatTable->antsel_b[macId], pDM_FatTable->antsel_a[macId])); + #endif + } + else if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + #if (RTL8188E_SUPPORT == 1) + SET_TX_DESC_ANTSEL_A_88E(pDesc, pDM_FatTable->antsel_a[macId]); + SET_TX_DESC_ANTSEL_B_88E(pDesc, pDM_FatTable->antsel_b[macId]); + SET_TX_DESC_ANTSEL_C_88E(pDesc, pDM_FatTable->antsel_c[macId]); + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[8188E] SetTxAntByTxInfo_WIN: MacID=%d, antsel_tr_mux=3'b%d%d%d\n", + //macId, pDM_FatTable->antsel_c[macId], pDM_FatTable->antsel_b[macId], pDM_FatTable->antsel_a[macId])); + #endif + } + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + + + } +} +#else// (DM_ODM_SUPPORT_TYPE == ODM_AP) + +VOID +ODM_SetTxAntByTxInfo( + //IN PDM_ODM_T pDM_Odm, + struct rtl8192cd_priv *priv, + struct tx_desc *pdesc, + struct tx_insn *txcfg, + unsigned short aid +) +{ + pFAT_T pDM_FatTable = &priv->pshare->_dmODM.DM_FatTable; + u4Byte SupportICType=priv->pshare->_dmODM.SupportICType; + + if(SupportICType == ODM_RTL8881A) + { + //panic_printk("[%s] [%d] ******ODM_SetTxAntByTxInfo_8881E****** \n",__FUNCTION__,__LINE__); + pdesc->Dword6 &= set_desc(~ (BIT(18)|BIT(17)|BIT(16))); + pdesc->Dword6 |= set_desc(pDM_FatTable->antsel_a[aid]<<16); + } + else if(SupportICType == ODM_RTL8192E) + { + //panic_printk("[%s] [%d] ******ODM_SetTxAntByTxInfo_8192E****** \n",__FUNCTION__,__LINE__); + pdesc->Dword6 &= set_desc(~ (BIT(18)|BIT(17)|BIT(16))); + pdesc->Dword6 |= set_desc(pDM_FatTable->antsel_a[aid]<<16); + } + else if(SupportICType == ODM_RTL8812) + { + //3 [path-A] + //panic_printk("[%s] [%d] ******ODM_SetTxAntByTxInfo_8881E****** \n",__FUNCTION__,__LINE__); + + pdesc->Dword6 &= set_desc(~ BIT(16)); + pdesc->Dword6 &= set_desc(~ BIT(17)); + pdesc->Dword6 &= set_desc(~ BIT(18)); + if(txcfg->pstat) + { + pdesc->Dword6 |= set_desc(pDM_FatTable->antsel_a[aid]<<16); + pdesc->Dword6 |= set_desc(pDM_FatTable->antsel_b[aid]<<17); + pdesc->Dword6 |= set_desc(pDM_FatTable->antsel_c[aid]<<18); + } + } +} +#endif + + +VOID +ODM_AntDiv_Config( + IN PDM_ODM_T pDM_Odm + ) +{ + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("WIN Config Antenna Diversity\n")); + if(pDM_Odm->SupportICType==ODM_RTL8723B) + { + if((!pDM_Odm->DM_SWAT_Table.ANTA_ON || !pDM_Odm->DM_SWAT_Table.ANTB_ON)) + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + } +#elif (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("CE Config Antenna Diversity\n")); + //if(pDM_Odm->SupportICType & ODM_ANTDIV_SUPPORT) + //{ + //pDM_Odm->SupportAbility |= ODM_BB_ANT_DIV; + //} + + if(pDM_Odm->SupportICType==ODM_RTL8723B) + { + pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + } + +#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("AP Config Antenna Diversity\n")); + + //2 [ NOT_SUPPORT_ANTDIV ] + #if(defined(CONFIG_NOT_SUPPORT_ANTDIV)) + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Disable AntDiv function] : Not Support 2.4G & 5G Antenna Diversity\n")); + + //2 [ 2G&5G_SUPPORT_ANTDIV ] + #elif(defined(CONFIG_2G5G_SUPPORT_ANTDIV)) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Enable AntDiv function] : 2.4G & 5G Support Antenna Diversity Simultaneously \n")); + pDM_FatTable->AntDiv_2G_5G = (ODM_ANTDIV_2G|ODM_ANTDIV_5G); + + if(pDM_Odm->SupportICType & ODM_ANTDIV_SUPPORT) + pDM_Odm->SupportAbility |= ODM_BB_ANT_DIV; + if(*pDM_Odm->pBandType == ODM_BAND_5G ) + { + #if ( defined(CONFIG_5G_CGCS_RX_DIVERSITY) ) + pDM_Odm->AntDivType = CGCS_RX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = CGCS_RX_HW_ANTDIV\n")); + panic_printk("[ 5G] : AntDiv Type = CGCS_RX_HW_ANTDIV\n"); + #elif( defined(CONFIG_5G_CG_TRX_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = CG_TRX_HW_ANTDIV\n")); + panic_printk("[ 5G] : AntDiv Type = CG_TRX_HW_ANTDIV\n"); + #elif( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_SMART_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = CG_SMART_ANTDIV\n")); + #elif( defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = S0S1_SW_ANTDIV\n")); + #endif + } + else if(*pDM_Odm->pBandType == ODM_BAND_2_4G ) + { + #if ( defined(CONFIG_2G_CGCS_RX_DIVERSITY) ) + pDM_Odm->AntDivType = CGCS_RX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = CGCS_RX_HW_ANTDIV\n")); + #elif( defined(CONFIG_2G_CG_TRX_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = CG_TRX_HW_ANTDIV\n")); + #elif( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_SMART_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = CG_SMART_ANTDIV\n")); + #elif( defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = S0S1_SW_ANTDIV\n")); + #endif + } + + //2 [ 5G_SUPPORT_ANTDIV ] + #elif(defined(CONFIG_5G_SUPPORT_ANTDIV)) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Enable AntDiv function] : Only 5G Support Antenna Diversity\n")); + panic_printk("[ Enable AntDiv function] : Only 5G Support Antenna Diversity\n"); + pDM_FatTable->AntDiv_2G_5G = (ODM_ANTDIV_5G); + if(*pDM_Odm->pBandType == ODM_BAND_5G ) + { + if(pDM_Odm->SupportICType & ODM_ANTDIV_5G_SUPPORT_IC) + pDM_Odm->SupportAbility |= ODM_BB_ANT_DIV; + #if ( defined(CONFIG_5G_CGCS_RX_DIVERSITY) ) + pDM_Odm->AntDivType = CGCS_RX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = CGCS_RX_HW_ANTDIV\n")); + panic_printk("[ 5G] : AntDiv Type = CGCS_RX_HW_ANTDIV\n"); + #elif( defined(CONFIG_5G_CG_TRX_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + panic_printk("[ 5G] : AntDiv Type = CG_TRX_HW_ANTDIV\n"); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = CG_TRX_HW_ANTDIV\n")); + #elif( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_SMART_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = CG_SMART_ANTDIV\n")); + #elif( defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 5G] : AntDiv Type = S0S1_SW_ANTDIV\n")); + #endif + } + else if(*pDM_Odm->pBandType == ODM_BAND_2_4G ) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Not Support 2G AntDivType\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + } + + //2 [ 2G_SUPPORT_ANTDIV ] + #elif(defined(CONFIG_2G_SUPPORT_ANTDIV)) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Enable AntDiv function] : Only 2.4G Support Antenna Diversity\n")); + pDM_FatTable->AntDiv_2G_5G = (ODM_ANTDIV_2G); + if(*pDM_Odm->pBandType == ODM_BAND_2_4G ) + { + if(pDM_Odm->SupportICType & ODM_ANTDIV_2G_SUPPORT_IC) + pDM_Odm->SupportAbility |= ODM_BB_ANT_DIV; + #if ( defined(CONFIG_2G_CGCS_RX_DIVERSITY) ) + pDM_Odm->AntDivType = CGCS_RX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = CGCS_RX_HW_ANTDIV\n")); + #elif( defined(CONFIG_2G_CG_TRX_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = CG_TRX_HW_ANTDIV\n")); + #elif( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = CG_TRX_SMART_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = CG_SMART_ANTDIV\n")); + #elif( defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY) ) + pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2.4G] : AntDiv Type = S0S1_SW_ANTDIV\n")); + #endif + } + else if(*pDM_Odm->pBandType == ODM_BAND_5G ) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Not Support 5G AntDivType\n")); + pDM_Odm->SupportAbility &= ~(ODM_BB_ANT_DIV); + } + #endif +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("SupportAbility = (( %x ))\n", pDM_Odm->SupportAbility )); + +} + + +VOID +ODM_AntDivTimers( + IN PDM_ODM_T pDM_Odm, + IN u1Byte state + ) +{ + if(state==INIT_ANTDIV_TIMMER) + { + #if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + ODM_InitializeTimer(pDM_Odm,&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer_8723B, + (RT_TIMER_CALL_BACK)ODM_SW_AntDiv_Callback, NULL, "SwAntennaSwitchTimer_8723B"); + #elif (RTL8188E_SUPPORT == 1) + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + ODM_InitializeTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer, + (RT_TIMER_CALL_BACK)odm_FastAntTrainingCallback, NULL, "FastAntTrainingTimer"); + #endif + #endif + } + else if(state==CANCEL_ANTDIV_TIMMER) + { + #if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + ODM_CancelTimer(pDM_Odm,&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer_8723B); + #elif (RTL8188E_SUPPORT == 1) + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + ODM_CancelTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer); + #endif + #endif + } + else if(state==RELEASE_ANTDIV_TIMMER) + { + #if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + ODM_ReleaseTimer(pDM_Odm,&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer_8723B); + #elif (RTL8188E_SUPPORT == 1) + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + ODM_ReleaseTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer); + #endif + #endif + } + +} + +#endif //#if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDiv.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDiv.h new file mode 100755 index 000000000000..1e88e11fef8e --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_AntDiv.h @@ -0,0 +1,217 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMANTDIV_H__ +#define __PHYDMANTDIV_H__ + +#define ANTDIV_VERSION "1.0" + +#define ANT1_2G 0 // = ANT2_5G +#define ANT2_2G 1 // = ANT1_5G + +//Antenna Diversty Control Type +#define ODM_AUTO_ANT 0 +#define ODM_FIX_MAIN_ANT 1 +#define ODM_FIX_AUX_ANT 2 + +#define TX_BY_REG 0 + +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) +#define ODM_RTL8881A 0 //Just for windows driver to jointly use ODM-driver +#endif + +#define ODM_ANTDIV_SUPPORT (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) +#define ODM_N_ANTDIV_SUPPORT (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B) +#define ODM_AC_ANTDIV_SUPPORT (ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) +#define ODM_SMART_ANT_SUPPORT (ODM_RTL8188E|ODM_RTL8192E) + +#define ODM_OLD_IC_ANTDIV_SUPPORT (ODM_RTL8723A|ODM_RTL8192C|ODM_RTL8192D) + +#define ODM_ANTDIV_2G_SUPPORT_IC (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8881A) +#define ODM_ANTDIV_5G_SUPPORT_IC (ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) +#define ODM_ANTDIV_2G BIT0 +#define ODM_ANTDIV_5G BIT1 + +#define ANTDIV_ON 1 +#define ANTDIV_OFF 0 + +#define INIT_ANTDIV_TIMMER 0 +#define CANCEL_ANTDIV_TIMMER 1 +#define RELEASE_ANTDIV_TIMMER 2 + +VOID +ODM_StopAntennaSwitchDm( + IN PDM_ODM_T pDM_Odm + ); +VOID +ODM_SetAntConfig( + IN PDM_ODM_T pDM_Odm, + IN u1Byte antSetting // 0=A, 1=B, 2=C, .... + ); + + + +#define SwAntDivRestAfterLink ODM_SwAntDivRestAfterLink +VOID ODM_SwAntDivRestAfterLink( IN PDM_ODM_T pDM_Odm); + +#if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) + +VOID +ODM_UpdateRxIdleAnt( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Ant +); + +VOID +odm_AntselStatistics( + IN PDM_ODM_T pDM_Odm, + IN u1Byte antsel_tr_mux, + IN u4Byte MacId, + IN u4Byte RxPWDBAll +); + +#if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_SW_AntDiv_Callback( + IN PRT_TIMER pTimer +); + +VOID +ODM_SW_AntDiv_WorkitemCallback( + IN PVOID pContext + ); + + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + +VOID +ODM_SW_AntDiv_Callback(void *FunctionContext); + +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +odm_S0S1_SwAntDivByCtrlFrame( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Step + ); + +VOID +odm_AntselStatisticsOfCtrlFrame( + IN PDM_ODM_T pDM_Odm, + IN u1Byte antsel_tr_mux, + IN u4Byte RxPWDBAll +); + +VOID +odm_S0S1_SwAntDivByCtrlFrame_ProcessRSSI( + IN PDM_ODM_T pDM_Odm, + IN PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo + ); + +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#endif + +#if(RTL8188E_SUPPORT == 1 || RTL8192E_SUPPORT == 1) +#if ( !(DM_ODM_SUPPORT_TYPE == ODM_CE)) +VOID +odm_FastAntTraining( + IN PDM_ODM_T pDM_Odm +); + +VOID +odm_FastAntTrainingCallback( + IN PDM_ODM_T pDM_Odm +); + +VOID +odm_FastAntTrainingWorkItemCallback( + IN PDM_ODM_T pDM_Odm +); +#endif +#endif + +VOID +ODM_AntDivInit( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_AntDivReset( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_AntDiv( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_Process_RSSIForAntDiv( + IN OUT PDM_ODM_T pDM_Odm, + IN PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo +); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +ODM_SetTxAntByTxInfo( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte pDesc, + IN u1Byte macId +); + +#else// (DM_ODM_SUPPORT_TYPE == ODM_AP) +VOID +ODM_SetTxAntByTxInfo( + //IN PDM_ODM_T pDM_Odm, + struct rtl8192cd_priv *priv, + struct tx_desc *pdesc, + struct tx_insn *txcfg, + unsigned short aid +); + +#endif + + +VOID +ODM_AntDiv_Config( + IN PDM_ODM_T pDM_Odm +); + + +VOID +ODM_UpdateRxIdleAnt_8723B( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Ant, + IN u4Byte DefaultAnt, + IN u4Byte OptionalAnt +); + +VOID +ODM_AntDivTimers( + IN PDM_ODM_T pDM_Odm, + IN u1Byte state +); + +#endif //#if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) +#endif //#ifndef __ODMANTDIV_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_CfoTracking.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_CfoTracking.c new file mode 100755 index 000000000000..489bc49806fe --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_CfoTracking.c @@ -0,0 +1,357 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +VOID +odm_SetCrystalCap( + IN PVOID pDM_VOID, + IN u1Byte CrystalCap +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PCFO_TRACKING pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK); + BOOLEAN bEEPROMCheck; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + bEEPROMCheck = (pHalData->EEPROMVersion >= 0x01)?TRUE:FALSE; +#else + bEEPROMCheck = TRUE; +#endif + + if(pCfoTrack->CrystalCap == CrystalCap) + return; + + pCfoTrack->CrystalCap = CrystalCap; + + if(pDM_Odm->SupportICType & ODM_RTL8192D) + { + ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x000000F0, CrystalCap & 0x0F); + ODM_SetBBReg(pDM_Odm, REG_AFE_PLL_CTRL, 0xF0000000, ((CrystalCap & 0xF0) >> 4)); + } + else if(pDM_Odm->SupportICType & ODM_RTL8188E) + { + // write 0x24[22:17] = 0x24[16:11] = CrystalCap + CrystalCap = CrystalCap & 0x3F; + ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x007ff800, (CrystalCap | (CrystalCap << 6))); + } + else if(pDM_Odm->SupportICType & ODM_RTL8812) + { + // write 0x2C[30:25] = 0x2C[24:19] = CrystalCap + CrystalCap = CrystalCap & 0x3F; + ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x7FF80000, (CrystalCap | (CrystalCap << 6))); + } + else if (((pDM_Odm->SupportICType & ODM_RTL8723A) && bEEPROMCheck) || + (pDM_Odm->SupportICType & ODM_RTL8723B) ||(pDM_Odm->SupportICType & ODM_RTL8192E) || + (pDM_Odm->SupportICType & ODM_RTL8821)) + { + // 0x2C[23:18] = 0x2C[17:12] = CrystalCap + CrystalCap = CrystalCap & 0x3F; + ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x00FFF000, (CrystalCap | (CrystalCap << 6))); + } + else if(pDM_Odm->SupportICType & ODM_RTL8821B) + { + // write 0x28[6:1] = 0x24[30:25] = CrystalCap + CrystalCap = CrystalCap & 0x3F; + ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x7E000000, CrystalCap); + ODM_SetBBReg(pDM_Odm, REG_AFE_PLL_CTRL, 0x7E, CrystalCap); + } + else if(pDM_Odm->SupportICType & ODM_RTL8814A) + { + // write 0x2C[26:21] = 0x2C[20:15] = CrystalCap + CrystalCap = CrystalCap & 0x3F; + ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x07FF8000, (CrystalCap | (CrystalCap << 6))); + } + else + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_SetCrystalCap(): Use default setting.\n")); + ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap | (CrystalCap << 6))); + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_SetCrystalCap(): CrystalCap = 0x%x\n", CrystalCap)); +} + +u1Byte +odm_GetDefaultCrytaltalCap( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte CrystalCap = 0x20; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + CrystalCap = pHalData->CrystalCap; +#else + prtl8192cd_priv priv = pDM_Odm->priv; + + if(priv->pmib->dot11RFEntry.xcap > 0) + CrystalCap = priv->pmib->dot11RFEntry.xcap; +#endif + + CrystalCap = CrystalCap & 0x3f; + + return CrystalCap; +} + +VOID +odm_SetATCStatus( + IN PVOID pDM_VOID, + IN BOOLEAN ATCStatus +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PCFO_TRACKING pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK); + + if(pCfoTrack->bATCStatus == ATCStatus) + return; + + ODM_SetBBReg(pDM_Odm, ODM_REG(BB_ATC,pDM_Odm), ODM_BIT(BB_ATC,pDM_Odm), ATCStatus); + pCfoTrack->bATCStatus = ATCStatus; +} + +BOOLEAN +odm_GetATCStatus( + IN PVOID pDM_VOID +) +{ + BOOLEAN ATCStatus; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ATCStatus = (BOOLEAN)ODM_GetBBReg(pDM_Odm, ODM_REG(BB_ATC,pDM_Odm), ODM_BIT(BB_ATC,pDM_Odm)); + return ATCStatus; +} + +VOID +ODM_CfoTrackingReset( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PCFO_TRACKING pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK); + u1Byte CrystalCap; + + pCfoTrack->DefXCap = odm_GetDefaultCrytaltalCap(pDM_Odm); + pCfoTrack->bAdjust = TRUE; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap); + odm_SetATCStatus(pDM_Odm, TRUE); +#else + if(pCfoTrack->CrystalCap > pCfoTrack->DefXCap) + { + for(CrystalCap = pCfoTrack->CrystalCap; CrystalCap >= pCfoTrack->DefXCap; CrystalCap--) + odm_SetCrystalCap(pDM_Odm, CrystalCap); + } + else + { + for(CrystalCap = pCfoTrack->CrystalCap; CrystalCap <= pCfoTrack->DefXCap; CrystalCap++) + odm_SetCrystalCap(pDM_Odm, CrystalCap); + } +#endif +} + +VOID +ODM_CfoTrackingInit( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PCFO_TRACKING pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK); + + pCfoTrack->DefXCap = pCfoTrack->CrystalCap = odm_GetDefaultCrytaltalCap(pDM_Odm); + pCfoTrack->bATCStatus = odm_GetATCStatus(pDM_Odm); + pCfoTrack->bAdjust = TRUE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking_init()=========> \n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking_init(): bATCStatus = %d, CrystalCap = 0x%x \n",pCfoTrack->bATCStatus, pCfoTrack->DefXCap)); +} + +VOID +ODM_CfoTracking( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PCFO_TRACKING pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK); + int CFO_kHz_A, CFO_kHz_B, CFO_ave = 0; + int CFO_ave_diff; + int CrystalCap = (int)pCfoTrack->CrystalCap; + u1Byte Adjust_Xtal = 1; + + //4 Support ability + if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Return: SupportAbility ODM_BB_CFO_TRACKING is disabled\n")); + return; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking()=========> \n")); + + if(!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly) + { + //4 No link or more than one entry + ODM_CfoTrackingReset(pDM_Odm); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Reset: bLinked = %d, bOneEntryOnly = %d\n", + pDM_Odm->bLinked, pDM_Odm->bOneEntryOnly)); + } + else + { + //3 1. CFO Tracking + //4 1.1 No new packet + if(pCfoTrack->packetCount == pCfoTrack->packetCount_pre) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): packet counter doesn't change\n")); + return; + } + pCfoTrack->packetCount_pre = pCfoTrack->packetCount; + + //4 1.2 Calculate CFO + CFO_kHz_A = (int)(pCfoTrack->CFO_tail[0] * 3125) / 1280; + CFO_kHz_B = (int)(pCfoTrack->CFO_tail[1] * 3125) / 1280; + + if(pDM_Odm->RFType < ODM_2T2R) + CFO_ave = CFO_kHz_A; + else + CFO_ave = (int)(CFO_kHz_A + CFO_kHz_B) >> 1; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): CFO_kHz_A = %dkHz, CFO_kHz_B = %dkHz, CFO_ave = %dkHz\n", + CFO_kHz_A, CFO_kHz_B, CFO_ave)); + + //4 1.3 Avoid abnormal large CFO + CFO_ave_diff = (pCfoTrack->CFO_ave_pre >= CFO_ave)?(pCfoTrack->CFO_ave_pre - CFO_ave):(CFO_ave - pCfoTrack->CFO_ave_pre); + if(CFO_ave_diff > 20 && pCfoTrack->largeCFOHit == 0 && !pCfoTrack->bAdjust) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): first large CFO hit\n")); + pCfoTrack->largeCFOHit = 1; + return; + } + else + pCfoTrack->largeCFOHit = 0; + pCfoTrack->CFO_ave_pre = CFO_ave; + + //4 1.4 Dynamic Xtal threshold + if(pCfoTrack->bAdjust == FALSE) + { + if(CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH)) + pCfoTrack->bAdjust = TRUE; + } + else + { + if(CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW)) + pCfoTrack->bAdjust = FALSE; + } + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + //4 1.5 BT case: Disable CFO tracking + if(pDM_Odm->bBtEnabled) + { + pCfoTrack->bAdjust = FALSE; + odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable CFO tracking for BT!!\n")); + } + + //4 1.6 Big jump + if(pCfoTrack->bAdjust) + { + if(CFO_ave > CFO_TH_XTAL_LOW) + Adjust_Xtal = Adjust_Xtal + ((CFO_ave - CFO_TH_XTAL_LOW) >> 2); + else if(CFO_ave < (-CFO_TH_XTAL_LOW)) + Adjust_Xtal = Adjust_Xtal + ((CFO_TH_XTAL_LOW - CFO_ave) >> 2); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Crystal cap offset = %d\n", Adjust_Xtal)); + } +#endif + + //4 1.7 Adjust Crystal Cap. + if(pCfoTrack->bAdjust) + { + if(CFO_ave > CFO_TH_XTAL_LOW) + CrystalCap = CrystalCap + Adjust_Xtal; + else if(CFO_ave < (-CFO_TH_XTAL_LOW)) + CrystalCap = CrystalCap - Adjust_Xtal; + + if(CrystalCap > 0x3f) + CrystalCap = 0x3f; + else if (CrystalCap < 0) + CrystalCap = 0; + + odm_SetCrystalCap(pDM_Odm, (u1Byte)CrystalCap); + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Crystal cap = 0x%x, Default Crystal cap = 0x%x\n", + pCfoTrack->CrystalCap, pCfoTrack->DefXCap)); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + return; + + //3 2. Dynamic ATC switch + if(CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC) + { + odm_SetATCStatus(pDM_Odm, FALSE); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable ATC!!\n")); + } + else + { + odm_SetATCStatus(pDM_Odm, TRUE); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Enable ATC!!\n")); + } +#endif + } +} + +VOID +ODM_ParsingCFO( + IN PVOID pDM_VOID, + IN PVOID pPktinfo_VOID, + IN s1Byte* pcfotail + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_PACKET_INFO_T pPktinfo = (PODM_PACKET_INFO_T)pPktinfo_VOID; + PCFO_TRACKING pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK); + u1Byte i; + + if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING)) + return; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(pPktinfo->bPacketMatchBSSID) +#else + if(pPktinfo->StationID != 0) +#endif + { + //3 Update CFO report for path-A & path-B + // Only paht-A and path-B have CFO tail and short CFO + for(i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++) + { + pCfoTrack->CFO_tail[i] = (int)pcfotail[i]; + } + + //3 Update packet counter + if(pCfoTrack->packetCount == 0xffffffff) + pCfoTrack->packetCount = 0; + else + pCfoTrack->packetCount++; + } +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_CfoTracking.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_CfoTracking.h new file mode 100755 index 000000000000..77e0a4baa3f1 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_CfoTracking.h @@ -0,0 +1,68 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMCFOTRACK_H__ +#define __PHYDMCFOTRACK_H__ + +#define CFO_TRACKING_VERSION "1.0" + +#define CFO_TH_XTAL_HIGH 20 // kHz +#define CFO_TH_XTAL_LOW 10 // kHz +#define CFO_TH_ATC 80 // kHz + +typedef struct _CFO_TRACKING_ +{ + BOOLEAN bATCStatus; + BOOLEAN largeCFOHit; + BOOLEAN bAdjust; + u1Byte CrystalCap; + u1Byte DefXCap; + int CFO_tail[2]; + int CFO_ave_pre; + u4Byte packetCount; + u4Byte packetCount_pre; + + BOOLEAN bForceXtalCap; + BOOLEAN bReset; +}CFO_TRACKING, *PCFO_TRACKING; + +VOID +ODM_CfoTrackingReset( + IN PVOID pDM_VOID +); + +VOID +ODM_CfoTrackingInit( + IN PVOID pDM_VOID +); + +VOID +ODM_CfoTracking( + IN PVOID pDM_VOID +); + +VOID +ODM_ParsingCFO( + IN PVOID pDM_VOID, + IN PVOID pPktinfo_VOID, + IN s1Byte* pcfotail +); + +#endif \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DIG.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DIG.c new file mode 100755 index 000000000000..4e6304fe50e7 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DIG.c @@ -0,0 +1,2023 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + + +VOID +ODM_ChangeDynamicInitGainThresh( + IN PVOID pDM_VOID, + IN u4Byte DM_Type, + IN u4Byte DM_Value + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + + if (DM_Type == DIG_TYPE_THRESH_HIGH) + { + pDM_DigTable->RssiHighThresh = DM_Value; + } + else if (DM_Type == DIG_TYPE_THRESH_LOW) + { + pDM_DigTable->RssiLowThresh = DM_Value; + } + else if (DM_Type == DIG_TYPE_ENABLE) + { + pDM_DigTable->Dig_Enable_Flag = TRUE; + } + else if (DM_Type == DIG_TYPE_DISABLE) + { + pDM_DigTable->Dig_Enable_Flag = FALSE; + } + else if (DM_Type == DIG_TYPE_BACKOFF) + { + if(DM_Value > 30) + DM_Value = 30; + pDM_DigTable->BackoffVal = (u1Byte)DM_Value; + } + else if(DM_Type == DIG_TYPE_RX_GAIN_MIN) + { + if(DM_Value == 0) + DM_Value = 0x1; + pDM_DigTable->rx_gain_range_min = (u1Byte)DM_Value; + } + else if(DM_Type == DIG_TYPE_RX_GAIN_MAX) + { + if(DM_Value > 0x50) + DM_Value = 0x50; + pDM_DigTable->rx_gain_range_max = (u1Byte)DM_Value; + } +} // DM_ChangeDynamicInitGainThresh // + +int +getIGIForDiff(int value_IGI) +{ + #define ONERCCA_LOW_TH 0x30 + #define ONERCCA_LOW_DIFF 8 + + if (value_IGI < ONERCCA_LOW_TH) { + if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF) + return ONERCCA_LOW_TH; + else + return value_IGI + ONERCCA_LOW_DIFF; + } else { + return value_IGI; + } +} + +VOID +odm_FAThresholdCheck( + IN PVOID pDM_VOID, + IN BOOLEAN bDFSBand, + IN BOOLEAN bPerformance, + IN u4Byte RxTp, + IN u4Byte TxTp, + OUT u4Byte* dm_FA_thres + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if(pDM_Odm->bLinked && (bPerformance||bDFSBand)) + { + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + // 8192D special case + dm_FA_thres[0] = DM_DIG_FA_TH0_92D; + dm_FA_thres[1] = DM_DIG_FA_TH1_92D; + dm_FA_thres[2] = DM_DIG_FA_TH2_92D; + } +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + else if(pDM_Odm->SupportPlatform & (ODM_AP|ODM_ADSL)) + { + // For AP + if((RxTp>>2) > TxTp && RxTp < 10000 && RxTp > 500) // 10Mbps & 0.5Mbps + { + dm_FA_thres[0] = 0x080; + dm_FA_thres[1] = 0x100; + dm_FA_thres[2] = 0x200; + } + else + { + dm_FA_thres[0] = 0x100; + dm_FA_thres[1] = 0x200; + dm_FA_thres[2] = 0x300; + } + } +#else + else if(pDM_Odm->SupportICType == ODM_RTL8723A && pDM_Odm->bBtLimitedDig) + { + // 8723A BT special case + dm_FA_thres[0] = DM_DIG_FA_TH0; + dm_FA_thres[1] = 0x250; + dm_FA_thres[2] = 0x300; + } +#endif + else + { + // For NIC + dm_FA_thres[0] = DM_DIG_FA_TH0; + dm_FA_thres[1] = DM_DIG_FA_TH1; + dm_FA_thres[2] = DM_DIG_FA_TH2; + } + } + else + { +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + if(bDFSBand) + { + // For DFS band and no link + dm_FA_thres[0] = 250; + dm_FA_thres[1] = 1000; + dm_FA_thres[2] = 2000; + } + else +#endif + { + dm_FA_thres[0] = 2000; + dm_FA_thres[1] = 4000; + dm_FA_thres[2] = 5000; + } + } + return; +} + +u1Byte +odm_ForbiddenIGICheck( + IN PVOID pDM_VOID, + IN u1Byte DIG_Dynamic_MIN, + IN u1Byte CurrentIGI + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); + u1Byte rx_gain_range_min = pDM_DigTable->rx_gain_range_min; + + if(pFalseAlmCnt->Cnt_all > 10000) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case. \n")); + + if(pDM_DigTable->LargeFAHit != 3) + pDM_DigTable->LargeFAHit++; + + if(pDM_DigTable->ForbiddenIGI < CurrentIGI)//if(pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) + { + pDM_DigTable->ForbiddenIGI = CurrentIGI;//pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; + pDM_DigTable->LargeFAHit = 1; + } + + if(pDM_DigTable->LargeFAHit >= 3) + { + if((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max) + rx_gain_range_min = pDM_DigTable->rx_gain_range_max; + else + rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); + pDM_DigTable->Recover_cnt = 1800; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case: Recover_cnt = %d \n", pDM_DigTable->Recover_cnt)); + } + } + else + { + if(pDM_DigTable->Recover_cnt != 0) + { + pDM_DigTable->Recover_cnt --; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Recover_cnt = %d \n", pDM_DigTable->Recover_cnt)); + } + else + { + if(pDM_DigTable->LargeFAHit < 3) + { + if((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) //DM_DIG_MIN) + { + pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; //DM_DIG_MIN; + rx_gain_range_min = DIG_Dynamic_MIN; //DM_DIG_MIN; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: At Lower Bound\n")); + } + else + { + pDM_DigTable->ForbiddenIGI -= 2; + rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Approach Lower Bound\n")); + } + } + else + { + pDM_DigTable->LargeFAHit = 0; + } + } + } + + return rx_gain_range_min; + +} + +VOID +odm_InbandNoiseCalculate ( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + u1Byte IGIBackup, TimeCnt = 0, ValidCnt = 0; + BOOLEAN bTimeout = TRUE; + s1Byte sNoise_A, sNoise_B; + s4Byte NoiseRpt_A = 0,NoiseRpt_B = 0; + u4Byte tmp = 0; + static u1Byte failCnt = 0; + + if(!(pDM_Odm->SupportICType & (ODM_RTL8192E))) + return; + + if(pDM_Odm->RFType == ODM_1T1R || *(pDM_Odm->pOnePathCCA) != ODM_CCA_2R) + return; + + if(!pDM_DigTable->bNoiseEst) + return; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_InbandNoiseEstimate()========>\n")); + + //1 Set initial gain. + IGIBackup = pDM_DigTable->CurIGValue; + pDM_DigTable->IGIOffset_A = 0; + pDM_DigTable->IGIOffset_B = 0; + ODM_Write_DIG(pDM_Odm, 0x24); + + //1 Update idle time power report + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + ODM_SetBBReg(pDM_Odm, ODM_REG_TX_ANT_CTRL_11N, BIT25, 0x0); + + delay_ms(2); + + //1 Get noise power level + while(1) + { + //2 Read Noise Floor Report + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + tmp = ODM_GetBBReg(pDM_Odm, 0x8f8, bMaskLWord); + + sNoise_A = (s1Byte)(tmp & 0xff); + sNoise_B = (s1Byte)((tmp & 0xff00)>>8); + + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("sNoise_A = %d, sNoise_B = %d\n",sNoise_A, sNoise_B)); + + if((sNoise_A < 20 && sNoise_A >= -70) && (sNoise_B < 20 && sNoise_B >= -70)) + { + ValidCnt++; + NoiseRpt_A += sNoise_A; + NoiseRpt_B += sNoise_B; + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("sNoise_A = %d, sNoise_B = %d\n",sNoise_A, sNoise_B)); + } + + TimeCnt++; + bTimeout = (TimeCnt >= 150)?TRUE:FALSE; + + if(ValidCnt == 20 || bTimeout) + break; + + delay_ms(2); + + } + + //1 Keep idle time power report + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + ODM_SetBBReg(pDM_Odm, ODM_REG_TX_ANT_CTRL_11N, BIT25, 0x1); + + //1 Recover IGI + ODM_Write_DIG(pDM_Odm, IGIBackup); + + //1 Calculate Noise Floor + if(ValidCnt != 0) + { + NoiseRpt_A /= (ValidCnt<<1); + NoiseRpt_B /= (ValidCnt<<1); + } + + if(bTimeout) + { + NoiseRpt_A = 0; + NoiseRpt_B = 0; + + failCnt ++; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("Noise estimate fail time = %d\n", failCnt)); + + if(failCnt == 3) + { + failCnt = 0; + pDM_DigTable->bNoiseEst = FALSE; + } + } + else + { + NoiseRpt_A = -110 + 0x24 + NoiseRpt_A -6; + NoiseRpt_B = -110 + 0x24 + NoiseRpt_B -6; + pDM_DigTable->bNoiseEst = FALSE; + failCnt = 0; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("NoiseRpt_A = %d, NoiseRpt_B = %d\n", NoiseRpt_A, NoiseRpt_B)); + } + + //1 Calculate IGI Offset + if(NoiseRpt_A > NoiseRpt_B) + { + pDM_DigTable->IGIOffset_A = NoiseRpt_A - NoiseRpt_B; + pDM_DigTable->IGIOffset_B = 0; + } + else + { + pDM_DigTable->IGIOffset_A = 0; + pDM_DigTable->IGIOffset_B = NoiseRpt_B - NoiseRpt_A; + } + +#endif + return; +} + +VOID +odm_DigForBtHsMode( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable=&pDM_Odm->DM_DigTable; + u1Byte digForBtHs=0; + u1Byte digUpBound=0x5a; + + if(pDM_Odm->bBtConnectProcess) + { + if(pDM_Odm->SupportICType&(ODM_RTL8723A)) + digForBtHs = 0x28; + else + digForBtHs = 0x22; + } + else + { + // + // Decide DIG value by BT HS RSSI. + // + digForBtHs = pDM_Odm->btHsRssi+4; + + //DIG Bound + if(pDM_Odm->SupportICType&(ODM_RTL8723A)) + digUpBound = 0x3e; + + if(digForBtHs > digUpBound) + digForBtHs = digUpBound; + if(digForBtHs < 0x1c) + digForBtHs = 0x1c; + + // update Current IGI + pDM_DigTable->BT30_CurIGI = digForBtHs; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DigForBtHsMode() : set DigValue=0x%x\n", digForBtHs)); +#endif +} + +VOID +ODM_Write_DIG( + IN PVOID pDM_VOID, + IN u1Byte CurrentIGI + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + + if(pDM_DigTable->bStopDIG) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("Stop Writing IGI\n")); + return; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_TRACE, ("ODM_REG(IGI_A,pDM_Odm)=0x%x, ODM_BIT(IGI,pDM_Odm)=0x%x \n", + ODM_REG(IGI_A,pDM_Odm),ODM_BIT(IGI,pDM_Odm))); + + if(pDM_DigTable->CurIGValue != CurrentIGI) + { + //1 Check initial gain by upper bound + if(!pDM_DigTable->bPSDInProgress) + { + if(CurrentIGI > pDM_DigTable->rx_gain_range_max) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_TRACE, ("CurrentIGI(0x%02x) is larger than upper bound !!\n",CurrentIGI)); + CurrentIGI = pDM_DigTable->rx_gain_range_max; + } + + } + + //1 Set IGI value + if(pDM_Odm->SupportPlatform & (ODM_WIN|ODM_CE)) + { + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + + if(pDM_Odm->RFType > ODM_1T1R) + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + + if((pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) && (pDM_Odm->RFType > ODM_2T2R)) + { + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_C,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_D,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + } + } + else if(pDM_Odm->SupportPlatform & (ODM_AP|ODM_ADSL)) + { + switch(*(pDM_Odm->pOnePathCCA)) + { + case ODM_CCA_2R: + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + + if(pDM_Odm->RFType > ODM_1T1R) + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + + if((pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) && (pDM_Odm->RFType > ODM_2T2R)) + { + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_C,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_D,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + } + break; + case ODM_CCA_1R_A: + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + if(pDM_Odm->RFType != ODM_1T1R) + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), getIGIForDiff(CurrentIGI)); + break; + case ODM_CCA_1R_B: + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), getIGIForDiff(CurrentIGI)); + if(pDM_Odm->RFType != ODM_1T1R) + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); + break; + } + } + pDM_DigTable->CurIGValue = CurrentIGI; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_TRACE, ("CurrentIGI(0x%02x). \n",CurrentIGI)); + +} + +VOID +odm_PauseDIG( + IN PVOID pDM_VOID, + IN ODM_Pause_DIG_TYPE PauseType, + IN u1Byte IGIValue +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG()=========>\n")); + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + if(*pDM_DigTable->pbP2pLinkInProgress) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): P2P in progress !!\n")); + return; + } +#endif + + if(!pDM_DigTable->bPauseDIG && (!(pDM_Odm->SupportAbility & ODM_BB_DIG) || !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Return: SupportAbility ODM_BB_DIG or ODM_BB_FA_CNT is disabled\n")); + return; + } + + switch(PauseType) + { + //1 Pause DIG + case ODM_PAUSE_DIG: + //2 Disable DIG + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility & (~ODM_BB_DIG)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Pause DIG !!\n")); + + //2 Backup IGI value + if(!pDM_DigTable->bPauseDIG) + { + pDM_DigTable->IGIBackup = pDM_DigTable->CurIGValue; + pDM_DigTable->bPauseDIG = TRUE; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Backup IGI = 0x%x\n", pDM_DigTable->IGIBackup)); + + //2 Write new IGI value + ODM_Write_DIG(pDM_Odm, IGIValue); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Write new IGI = 0x%x\n", IGIValue)); + break; + + //1 Resume DIG + case ODM_RESUME_DIG: + if(pDM_DigTable->bPauseDIG) + { + //2 Write backup IGI value + ODM_Write_DIG(pDM_Odm, pDM_DigTable->IGIBackup); + pDM_DigTable->bPauseDIG = FALSE; + pDM_DigTable->bIgnoreDIG = TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Write original IGI = 0x%x\n", pDM_DigTable->IGIBackup)); + + //2 Enable DIG + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_DIG); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Resume DIG !!\n")); + } + break; + + default: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Wrong type !!\n")); + break; + } +} + +BOOLEAN +odm_DigAbort( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER pAdapter = pDM_Odm->Adapter; + pRXHP_T pRX_HP_Table = &pDM_Odm->DM_RXHP_Table; +#endif + + //SupportAbility + if(!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: SupportAbility ODM_BB_FA_CNT is disabled\n")); + return TRUE; + } + + //SupportAbility + if(!(pDM_Odm->SupportAbility & ODM_BB_DIG)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: SupportAbility ODM_BB_DIG is disabled\n")); + return TRUE; + } + + //ScanInProcess + if(*(pDM_Odm->pbScanInProcess)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: In Scan Progress \n")); + return TRUE; + } + + if(pDM_DigTable->bIgnoreDIG) + { + pDM_DigTable->bIgnoreDIG = FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Ignore DIG \n")); + return TRUE; + } + + //add by Neil Chen to avoid PSD is processing + if(pDM_Odm->bDMInitialGainEnable == FALSE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: PSD is Processing \n")); + return TRUE; + } + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if OS_WIN_FROM_WIN7(OS_VERSION) + if(IsAPModeExist( pAdapter) && pAdapter->bInHctTest) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Is AP mode or In HCT Test \n")); + return TRUE; + } + #endif + + if(pDM_Odm->bBtHsOperation) + { + odm_DigForBtHsMode(pDM_Odm); + } + + if(!(pDM_Odm->SupportICType &(ODM_RTL8723A|ODM_RTL8188E))) + { + if(pRX_HP_Table->RXHP_flag == 1) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: In RXHP Operation \n")); + return TRUE; + } + } +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + if((pDM_Odm->bLinked) && (pDM_Odm->Adapter->registrypriv.force_igi !=0)) + { + printk("pDM_Odm->RSSI_Min=%d \n",pDM_Odm->RSSI_Min); + ODM_Write_DIG(pDM_Odm,pDM_Odm->Adapter->registrypriv.force_igi); + return TRUE; + } + #endif +#else + if (!(priv->up_time > 5)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Not In DIG Operation Period \n")); + return TRUE; + } +#endif + + return FALSE; +} + +VOID +odm_DIGInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); +#endif + + pDM_DigTable->bStopDIG = FALSE; + pDM_DigTable->bPauseDIG = FALSE; + pDM_DigTable->bIgnoreDIG = FALSE; + pDM_DigTable->bPSDInProgress = FALSE; + pDM_DigTable->CurIGValue = (u1Byte) ODM_GetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm)); + pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; + pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; + pDM_DigTable->FALowThresh = DM_FALSEALARM_THRESH_LOW; + pDM_DigTable->FAHighThresh = DM_FALSEALARM_THRESH_HIGH; + pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; + pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; + pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; + pDM_DigTable->PreCCK_CCAThres = 0xFF; + pDM_DigTable->CurCCK_CCAThres = 0x83; + pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC; + pDM_DigTable->LargeFAHit = 0; + pDM_DigTable->Recover_cnt = 0; + pDM_DigTable->bMediaConnect_0 = FALSE; + pDM_DigTable->bMediaConnect_1 = FALSE; + + //To Initialize pDM_Odm->bDMInitialGainEnable == FALSE to avoid DIG error + pDM_Odm->bDMInitialGainEnable = TRUE; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + pDM_DigTable->DIG_Dynamic_MIN_0 = 0x25; + pDM_DigTable->DIG_Dynamic_MIN_1 = 0x25; + + // For AP\ ADSL modified DIG + pDM_DigTable->bTpTarget = FALSE; + pDM_DigTable->bNoiseEst = TRUE; + pDM_DigTable->IGIOffset_A = 0; + pDM_DigTable->IGIOffset_B = 0; + pDM_DigTable->TpTrainTH_min = 0; + + // For RTL8881A + FalseAlmCnt->Cnt_Ofdm_fail_pre = 0; + + //Dyanmic EDCCA + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + ODM_SetBBReg(pDM_Odm, 0xC50, 0xFFFF0000, 0xfafd); + } +#else + pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC; + pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC; + + //To Initi BT30 IGI + pDM_DigTable->BT30_CurIGI=0x32; + + #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + *pDM_DigTable->pbP2pLinkInProgress= FALSE; + #endif +#endif + + if(pDM_Odm->BoardType & (ODM_BOARD_EXT_PA|ODM_BOARD_EXT_LNA)) + { + pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; + pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; + } + else + { + pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; + pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; + } + +} + + +VOID +odm_DIG( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER pAdapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pDM_Odm->Adapter); +#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + PSTA_INFO_T pEntry; +#endif + + // Common parameters + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); + BOOLEAN FirstConnect,FirstDisConnect; + u1Byte DIG_MaxOfMin, DIG_Dynamic_MIN; + u1Byte dm_dig_max, dm_dig_min; + u1Byte CurrentIGI = pDM_DigTable->CurIGValue; + u1Byte offset; + u4Byte dm_FA_thres[3]; + u1Byte Adap_IGI_Upper = 0; + u4Byte TxTp = 0, RxTp = 0; + BOOLEAN bDFSBand = FALSE; + BOOLEAN bPerformance = TRUE, bFirstTpTarget = FALSE, bFirstCoverage = FALSE; +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + u4Byte TpTrainTH_MIN = DM_DIG_TP_Target_TH0; + static u1Byte TimeCnt = 0; + u1Byte i; +#endif + + if(odm_DigAbort(pDM_Odm) == TRUE) + return; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG()===========================>\n\n")); + + if(pDM_Odm->adaptivity_flag == TRUE) + Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper; + + + //1 Update status +#if (RTL8192D_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + if(*(pDM_Odm->pMacPhyMode) == ODM_DMSP) + { + if(*(pDM_Odm->pbMasterOfDMSP)) + { + DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; + FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == FALSE); + FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == TRUE); + } + else + { + DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_1; + FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1 == FALSE); + FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1 == TRUE); + } + } + else + { + if(*(pDM_Odm->pBandType) == ODM_BAND_5G) + { + DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; + FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == FALSE); + FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == TRUE); + } + else + { + DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_1; + FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1 == FALSE); + FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1 == TRUE); + } + } + } + else +#endif + { + DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; + FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == FALSE); + FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == TRUE); + } + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + //1 Noise Floor Estimate + //pDM_DigTable->bNoiseEst = (FirstConnect)?TRUE:pDM_DigTable->bNoiseEst; + //odm_InbandNoiseCalculate (pDM_Odm); + + //1 Mode decision + if(pDM_Odm->bLinked) + { + //2 Calculate total TP + for (i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pEntry)) + { + RxTp += (u4Byte)(pEntry->rx_byte_cnt_LowMAW>>7); + TxTp += (u4Byte)(pEntry->tx_byte_cnt_LowMAW>>7); //Kbps + } + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): TX TP = %dkbps, RX TP = %dkbps\n", TxTp, RxTp)); + } + + switch(pDM_Odm->priv->pshare->rf_ft_var.dig_cov_enable) + { + case 0: + { + bPerformance = TRUE; + break; + } + case 1: + { + bPerformance = FALSE; + break; + } + case 2: + { + if(pDM_Odm->bLinked) + { + if(pDM_DigTable->TpTrainTH_min > DM_DIG_TP_Target_TH0) + TpTrainTH_MIN = pDM_DigTable->TpTrainTH_min; + + if(pDM_DigTable->TpTrainTH_min > DM_DIG_TP_Target_TH1) + TpTrainTH_MIN = DM_DIG_TP_Target_TH1; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): TP training mode lower bound = %dkbps\n", TpTrainTH_MIN)); + + //2 Decide DIG mode by total TP + if((TxTp + RxTp) > DM_DIG_TP_Target_TH1) // change to performance mode + { + bFirstTpTarget = (!pDM_DigTable->bTpTarget)?TRUE:FALSE; + pDM_DigTable->bTpTarget = TRUE; + bPerformance = TRUE; + } + else if((TxTp + RxTp) < TpTrainTH_MIN) // change to coverage mode + { + bFirstCoverage = (pDM_DigTable->bTpTarget)?TRUE:FALSE; + + if(TimeCnt < DM_DIG_TP_Training_Period) + { + pDM_DigTable->bTpTarget = FALSE; + bPerformance = FALSE; + TimeCnt++; + } + else + { + pDM_DigTable->bTpTarget = TRUE; + bPerformance = TRUE; + bFirstTpTarget = TRUE; + TimeCnt = 0; + } + } + else // remain previous mode + { + bPerformance = pDM_DigTable->bTpTarget; + + if(!bPerformance) + { + if(TimeCnt < DM_DIG_TP_Training_Period) + TimeCnt++; + else + { + pDM_DigTable->bTpTarget = TRUE; + bPerformance = TRUE; + bFirstTpTarget = TRUE; + TimeCnt = 0; + } + } + } + + if(!bPerformance) + pDM_DigTable->TpTrainTH_min = RxTp + TxTp; + + } + else + { + bPerformance = FALSE; + pDM_DigTable->TpTrainTH_min = 0; + } + break; + } + default: + bPerformance = TRUE; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("====== DIG mode = %d ======\n", pDM_Odm->priv->pshare->rf_ft_var.dig_cov_enable)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("====== bPerformance = %d ======\n", bPerformance)); +#endif + + //1 Boundary Decision +#if (RTL8192C_SUPPORT==1) + if((pDM_Odm->SupportICType & ODM_RTL8192C) && (pDM_Odm->BoardType & (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_PA))) + { + //2 High power case + if(pDM_Odm->SupportPlatform & (ODM_AP|ODM_ADSL)) + { + dm_dig_max = DM_DIG_MAX_AP_HP; + dm_dig_min = DM_DIG_MIN_AP_HP; + } + else + { + dm_dig_max = DM_DIG_MAX_NIC_HP; + dm_dig_min = DM_DIG_MIN_NIC_HP; + } + DIG_MaxOfMin = DM_DIG_MAX_AP_HP; + } + else +#endif + { +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + //2 For AP\ADSL + if(!bPerformance) + { + dm_dig_max = DM_DIG_MAX_AP_COVERAGR; + dm_dig_min = DM_DIG_MIN_AP_COVERAGE; + DIG_MaxOfMin = DM_DIG_MAX_OF_MIN_COVERAGE; + } + else + { + dm_dig_max = DM_DIG_MAX_AP; + dm_dig_min = DM_DIG_MIN_AP; + DIG_MaxOfMin = DM_DIG_MAX_OF_MIN; + } + + //4 DFS band + if (((*pDM_Odm->pChannel>= 52) &&(*pDM_Odm->pChannel <= 64)) || + ((*pDM_Odm->pChannel >= 100) && (*pDM_Odm->pChannel <= 140))) + { + bDFSBand = TRUE; + dm_dig_min = DM_DIG_MIN_AP_DFS; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): ====== In DFS band ======\n")); + } + + //4 TX2path + if (priv->pmib->dot11RFEntry.tx2path && !bDFSBand && (*(pDM_Odm->pWirelessMode) == ODM_WM_B)) + dm_dig_max = 0x2A; + +#if RTL8192E_SUPPORT +#ifdef HIGH_POWER_EXT_LNA + if ((pDM_Odm->SupportICType & (ODM_RTL8192E)) && (pDM_Odm->ExtLNA)) + dm_dig_max = 0x42; +#endif +#endif + +#else + //2 For WIN\CE + if(pDM_Odm->SupportICType >= ODM_RTL8188E) + dm_dig_max = 0x5A; + else + dm_dig_max = DM_DIG_MAX_NIC; + + if(pDM_Odm->SupportICType != ODM_RTL8821) + dm_dig_min = DM_DIG_MIN_NIC; + else + dm_dig_min = 0x1C; + + DIG_MaxOfMin = DM_DIG_MAX_AP; +#endif + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Absolutly upper bound = 0x%x, lower bound = 0x%x\n",dm_dig_max, dm_dig_min)); + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + // for P2P case + if(0 < *pDM_Odm->pu1ForcedIgiLb) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): P2P case: Force IGI lb to: %u !!!!!!\n", *pDM_Odm->pu1ForcedIgiLb)); + dm_dig_min = *pDM_Odm->pu1ForcedIgiLb; + dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) : (dm_dig_min + 1); + } +#endif + + //1 Adjust boundary by RSSI + if(pDM_Odm->bLinked && bPerformance) + { + //2 Modify DIG upper bound +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + offset = 15; +#else + //4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT + if((pDM_Odm->SupportICType & (ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8812|ODM_RTL8821|ODM_RTL8723A)) && (pDM_Odm->bBtLimitedDig==1)) + { + offset = 10; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Coex. case: Force upper bound to RSSI + %d !!!!!!\n", offset)); + } + else + offset = 15; +#endif + + if((pDM_Odm->RSSI_Min + offset) > dm_dig_max ) + pDM_DigTable->rx_gain_range_max = dm_dig_max; + else if((pDM_Odm->RSSI_Min + offset) < dm_dig_min ) + pDM_DigTable->rx_gain_range_max = dm_dig_min; + else + pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + //2 Modify DIG lower bound + //if(pDM_Odm->bOneEntryOnly) + { + if(pDM_Odm->RSSI_Min < dm_dig_min) + DIG_Dynamic_MIN = dm_dig_min; + else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) + DIG_Dynamic_MIN = DIG_MaxOfMin; + else + DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; + } +#else + { + //4 For AP +#ifdef __ECOS + HAL_REORDER_BARRIER(); +#else + rmb(); +#endif + if (bDFSBand) + { + DIG_Dynamic_MIN = dm_dig_min; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: Force lower bound to 0x%x after link !!!!!!\n", dm_dig_min)); + } + else + { + if(pDM_Odm->RSSI_Min < dm_dig_min) + DIG_Dynamic_MIN = dm_dig_min; + else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) + DIG_Dynamic_MIN = DIG_MaxOfMin; + else + DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; + } + } +#endif + } + else + { +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + if(bPerformance && bDFSBand) + { + pDM_DigTable->rx_gain_range_max = 0x28; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: Force upper bound to 0x%x before link !!!!!!\n", pDM_DigTable->rx_gain_range_max)); + } + else +#endif + { + pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_OF_MIN; + } + DIG_Dynamic_MIN = dm_dig_min; + } + + //1 Force Lower Bound for AntDiv + if(pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) + { + if((pDM_Odm->SupportICType & ODM_ANTDIV_SUPPORT) && (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) + { + if(pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV || pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||pDM_Odm->AntDivType == S0S1_SW_ANTDIV) + { + if(pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin) + DIG_Dynamic_MIN = DIG_MaxOfMin; + else + DIG_Dynamic_MIN = (u1Byte) pDM_DigTable->AntDiv_RSSI_max; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_DIG(): Antenna diversity case: Force lower bound to 0x%x !!!!!!\n", DIG_Dynamic_MIN)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_DIG(): Antenna diversity case: RSSI_max = 0x%x !!!!!!\n", pDM_DigTable->AntDiv_RSSI_max)); + } + } + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n", + pDM_DigTable->rx_gain_range_max, DIG_Dynamic_MIN)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Link status: bLinked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n\n", + pDM_Odm->bLinked, pDM_Odm->RSSI_Min, FirstConnect, FirstDisConnect)); + + //1 Modify DIG lower bound, deal with abnormal case + //2 Abnormal false alarm case +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + if(bDFSBand) + { + pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; + } + else +#endif + { + if(!pDM_Odm->bLinked) + { + pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; + + if(FirstDisConnect) + pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; + } + else + pDM_DigTable->rx_gain_range_min = odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI); + } + + //2 Abnormal # beacon case +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(pDM_Odm->bLinked && !FirstConnect) + { + if((pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && (pDM_Odm->bsta_state)) + { + pDM_DigTable->rx_gain_range_min = dm_dig_min; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x !!!!!!\n\n", + pDM_Odm->PhyDbgInfo.NumQryBeaconPkt, pDM_DigTable->rx_gain_range_min)); + } + } +#endif + + //2 Abnormal lower bound case + if(pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) + { + pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnrormal lower bound case: Force lower bound to 0x%x !!!!!!\n\n",pDM_DigTable->rx_gain_range_min)); + } + + + //1 False alarm threshold decision + odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): False alarm threshold = %d, %d, %d \n\n", dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2])); + + //1 Adjust initial gain by false alarm + if(pDM_Odm->bLinked && bPerformance) + { + //2 After link + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust IGI after link\n")); + + if(bFirstTpTarget || (FirstConnect && bPerformance)) + { + pDM_DigTable->LargeFAHit = 0; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + if(bDFSBand) + { + if(pDM_Odm->RSSI_Min > 0x28) + CurrentIGI = 0x28; + else + CurrentIGI = pDM_Odm->RSSI_Min; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: One-shot to 0x28 upmost!!!!!!\n")); + } + else +#endif + { + if(pDM_Odm->RSSI_Min < DIG_MaxOfMin) + { + if(CurrentIGI < pDM_Odm->RSSI_Min) + CurrentIGI = pDM_Odm->RSSI_Min; + } + else + { + if(CurrentIGI < DIG_MaxOfMin) + CurrentIGI = DIG_MaxOfMin; + } + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +#if (RTL8812A_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8812) + ODM_ConfigBBWithHeaderFile(pDM_Odm, CONFIG_BB_AGC_TAB_DIFF); +#endif +#endif + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): First connect case: IGI does on-shot to 0x%x\n", CurrentIGI)); + + } + else + { + if(pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) + CurrentIGI = CurrentIGI + 4; + else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) + CurrentIGI = CurrentIGI + 2; + else if(pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) + CurrentIGI = CurrentIGI - 2; + + //4 Abnormal # beacon case +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if((pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) && (pDM_Odm->bsta_state)) + { + CurrentIGI = pDM_DigTable->rx_gain_range_min; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n", + pDM_Odm->PhyDbgInfo.NumQryBeaconPkt, CurrentIGI)); + } +#endif + } + } + else + { + //2 Before link + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust IGI before link\n")); + + if(FirstDisConnect || bFirstCoverage) + { + CurrentIGI = dm_dig_min; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): First disconnect case: IGI does on-shot to lower bound\n")); + } + else + { + if(pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) + CurrentIGI = CurrentIGI + 4; + else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) + CurrentIGI = CurrentIGI + 2; + else if(pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) + CurrentIGI = CurrentIGI - 2; + } + } + + //1 Check initial gain by upper/lower bound + if(CurrentIGI < pDM_DigTable->rx_gain_range_min) + CurrentIGI = pDM_DigTable->rx_gain_range_min; + + if(CurrentIGI > pDM_DigTable->rx_gain_range_max) + CurrentIGI = pDM_DigTable->rx_gain_range_max; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): CurIGValue=0x%x, TotalFA = %d\n\n", CurrentIGI, pFalseAlmCnt->Cnt_all)); + + //1 Force upper bound and lower bound for adaptivity + if(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY && pDM_Odm->adaptivity_flag == TRUE) + { + if(CurrentIGI > Adap_IGI_Upper) + CurrentIGI = Adap_IGI_Upper; + + if(pDM_Odm->IGI_LowerBound != 0) + { + if(CurrentIGI < pDM_Odm->IGI_LowerBound) + CurrentIGI = pDM_Odm->IGI_LowerBound; + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adaptivity case: Force upper bound to 0x%x !!!!!!\n", Adap_IGI_Upper)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adaptivity case: Force lower bound to 0x%x !!!!!!\n\n", pDM_Odm->IGI_LowerBound)); + } + + + //1 High power RSSI threshold +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + if((pDM_Odm->SupportICType == ODM_RTL8723A)&& (pHalData->UndecoratedSmoothedPWDB > DM_DIG_HIGH_PWR_THRESHOLD)) + { + // High power IGI lower bound + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): UndecoratedSmoothedPWDB(%#x)\n", pHalData->UndecoratedSmoothedPWDB)); + if(CurrentIGI < DM_DIG_HIGH_PWR_IGI_LOWER_BOUND) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): CurIGValue(%#x)\n", pDM_DigTable->CurIGValue)); + //pDM_DigTable->CurIGValue = DM_DIG_HIGH_PWR_IGI_LOWER_BOUND; + CurrentIGI=DM_DIG_HIGH_PWR_IGI_LOWER_BOUND; + } + } + if((pDM_Odm->SupportICType & ODM_RTL8723A) && IS_WIRELESS_MODE_G(pAdapter)) + { + if(pHalData->UndecoratedSmoothedPWDB > 0x28) + { + if(CurrentIGI < DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND) + { + //pDM_DigTable->CurIGValue = DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND; + CurrentIGI = DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND; + } + } + } +#endif + + //1 Update status +#if (RTL8192D_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + //sherry delete DualMacSmartConncurrent 20110517 + if(*(pDM_Odm->pMacPhyMode) == ODM_DMSP) + { + ODM_Write_DIG_DMSP(pDM_Odm, CurrentIGI);//ODM_Write_DIG_DMSP(pDM_Odm, pDM_DigTable->CurIGValue); + if(*(pDM_Odm->pbMasterOfDMSP)) + { + pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; + pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; + } + else + { + pDM_DigTable->bMediaConnect_1 = pDM_Odm->bLinked; + pDM_DigTable->DIG_Dynamic_MIN_1 = DIG_Dynamic_MIN; + } + } + else + { + ODM_Write_DIG(pDM_Odm, CurrentIGI);//ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); + if(*(pDM_Odm->pBandType) == ODM_BAND_5G) + { + pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; + pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; + } + else + { + pDM_DigTable->bMediaConnect_1 = pDM_Odm->bLinked; + pDM_DigTable->DIG_Dynamic_MIN_1 = DIG_Dynamic_MIN; + } + } + } + else +#endif + { +#if ((DM_ODM_SUPPORT_TYPE & ODM_WIN) || ((DM_ODM_SUPPORT_TYPE & ODM_CE) && (ODM_CONFIG_BT_COEXIST == 1))) + if(pDM_Odm->bBtHsOperation) + { + if(pDM_Odm->bLinked) + { + if(pDM_DigTable->BT30_CurIGI > (CurrentIGI)) + ODM_Write_DIG(pDM_Odm, CurrentIGI); + else + ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI); + + pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; + pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; + } + else + { + if(pDM_Odm->bLinkInProcess) + ODM_Write_DIG(pDM_Odm, 0x1c); + else if(pDM_Odm->bBtConnectProcess) + ODM_Write_DIG(pDM_Odm, 0x28); + else + ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);//ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); + } + } + else // BT is not using +#endif + { + ODM_Write_DIG(pDM_Odm, CurrentIGI);//ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); + pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; + pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; + } + } +} + +VOID +odm_DIGbyRSSI_LPS( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); + +#if (DM_ODM_SUPPORT_TYPE & ODM_CE) +#if 0 //and 2.3.5 coding rule + struct mlme_priv *pmlmepriv = &(pAdapter->mlmepriv); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; +#endif +#endif + + u1Byte RSSI_Lower=DM_DIG_MIN_NIC; //0x1E or 0x1C + u1Byte CurrentIGI=pDM_Odm->RSSI_Min; + + if(odm_DigAbort(pDM_Odm) == TRUE) + return; + + CurrentIGI=CurrentIGI+RSSI_OFFSET_DIG; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS()==>\n")); + + // Using FW PS mode to make IGI + //Adjust by FA in LPS MODE + if(pFalseAlmCnt->Cnt_all> DM_DIG_FA_TH2_LPS) + CurrentIGI = CurrentIGI+4; + else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS) + CurrentIGI = CurrentIGI+2; + else if(pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS) + CurrentIGI = CurrentIGI-2; + + + //Lower bound checking + + //RSSI Lower bound check + if((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC) + RSSI_Lower =(pDM_Odm->RSSI_Min-10); + else + RSSI_Lower =DM_DIG_MIN_NIC; + + //Upper and Lower Bound checking + if(CurrentIGI > DM_DIG_MAX_NIC) + CurrentIGI=DM_DIG_MAX_NIC; + else if(CurrentIGI < RSSI_Lower) + CurrentIGI =RSSI_Lower; + + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS(): pFalseAlmCnt->Cnt_all = %d\n",pFalseAlmCnt->Cnt_all)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS(): pDM_Odm->RSSI_Min = %d\n",pDM_Odm->RSSI_Min)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS(): CurrentIGI = 0x%x\n",CurrentIGI)); + + ODM_Write_DIG(pDM_Odm, CurrentIGI);//ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); +#endif +} + +//3============================================================ +//3 FASLE ALARM CHECK +//3============================================================ + +VOID +odm_FalseAlarmCounterStatistics( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); + u4Byte ret_value; + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +//Mark there, and check this in odm_DMWatchDog +#if 0 //(DM_ODM_SUPPORT_TYPE == ODM_AP) + prtl8192cd_priv priv = pDM_Odm->priv; + if( (priv->auto_channel != 0) && (priv->auto_channel != 2) ) + return; +#endif +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if((pDM_Odm->SupportICType == ODM_RTL8192D) && + (*(pDM_Odm->pMacPhyMode)==ODM_DMSP)&& ////modify by Guo.Mingzhi 2011-12-29 + (!(*(pDM_Odm->pbMasterOfDMSP)))) + { + odm_FalseAlarmCounterStatistics_ForSlaveOfDMSP(pDM_Odm); + return; + } +#endif + + if(!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) + return; + +#if (ODM_IC_11N_SERIES_SUPPORT == 1) + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + + //hold ofdm counter + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1); //hold page C counter + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1); //hold page D counter + + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); + FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); + FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); + + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); + FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); + FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); + + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); + FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); + FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); + + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); + FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); + + FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail + FalseAlmCnt->Cnt_Rate_Illegal + + FalseAlmCnt->Cnt_Crc8_fail + FalseAlmCnt->Cnt_Mcs_fail + + FalseAlmCnt->Cnt_Fast_Fsync + FalseAlmCnt->Cnt_SB_Search_fail; + +#if (RTL8188E_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_SC_CNT_11N, bMaskDWord); + FalseAlmCnt->Cnt_BW_LSC = (ret_value&0xffff); + FalseAlmCnt->Cnt_BW_USC = ((ret_value&0xffff0000)>>16); + } +#endif + +#if (RTL8192D_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + odm_GetCCKFalseAlarm_92D(pDM_Odm); + } + else +#endif + { + //hold cck counter + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT12, 1); + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT14, 1); + + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_LSB_11N, bMaskByte0); + FalseAlmCnt->Cnt_Cck_fail = ret_value; + + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); + FalseAlmCnt->Cnt_Cck_fail += (ret_value& 0xff)<<8; + + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord); + FalseAlmCnt->Cnt_CCK_CCA = ((ret_value&0xFF)<<8) |((ret_value&0xFF00)>>8); + } + + FalseAlmCnt->Cnt_all = ( FalseAlmCnt->Cnt_Fast_Fsync + + FalseAlmCnt->Cnt_SB_Search_fail + + FalseAlmCnt->Cnt_Parity_Fail + + FalseAlmCnt->Cnt_Rate_Illegal + + FalseAlmCnt->Cnt_Crc8_fail + + FalseAlmCnt->Cnt_Mcs_fail + + FalseAlmCnt->Cnt_Cck_fail); + + FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; + +#if (RTL8192C_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8192C) + odm_ResetFACounter_92C(pDM_Odm); +#endif + +#if (RTL8192D_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8192D) + odm_ResetFACounter_92D(pDM_Odm); +#endif + + if(pDM_Odm->SupportICType >=ODM_RTL8723A) + { + //reset false alarm counter registers + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT31, 1); + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT31, 0); + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT27, 1); + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT27, 0); + + //update ofdm counter + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 0); //update page C counter + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 0); //update page D counter + + //reset CCK CCA counter + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT13|BIT12, 0); + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT13|BIT12, 2); + //reset CCK FA counter + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT15|BIT14, 0); + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT15|BIT14, 2); + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Enter odm_FalseAlarmCounterStatistics\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Fast_Fsync=%d, Cnt_SB_Search_fail=%d\n", + FalseAlmCnt->Cnt_Fast_Fsync, FalseAlmCnt->Cnt_SB_Search_fail)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Parity_Fail=%d, Cnt_Rate_Illegal=%d\n", + FalseAlmCnt->Cnt_Parity_Fail, FalseAlmCnt->Cnt_Rate_Illegal)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Crc8_fail=%d, Cnt_Mcs_fail=%d\n", + FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail)); + } +#endif + +#if (ODM_IC_11AC_SERIES_SUPPORT == 1) + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + u4Byte CCKenable; + + //read OFDM FA counter + FalseAlmCnt->Cnt_Ofdm_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_11AC, bMaskLWord); + FalseAlmCnt->Cnt_Cck_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_11AC, bMaskLWord); + + //read CCK/OFDM CCA counter + ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11AC, bMaskDWord); + FalseAlmCnt->Cnt_OFDM_CCA = (ret_value & 0xffff0000) >> 16; + FalseAlmCnt->Cnt_CCK_CCA = ret_value & 0xffff; + +#if (RTL8881A_SUPPORT==1) + // For 8881A + if(pDM_Odm->SupportICType == ODM_RTL8881A) + { + u4Byte Cnt_Ofdm_fail_temp = 0; + + if(FalseAlmCnt->Cnt_Ofdm_fail >= FalseAlmCnt->Cnt_Ofdm_fail_pre) + { + Cnt_Ofdm_fail_temp = FalseAlmCnt->Cnt_Ofdm_fail_pre; + FalseAlmCnt->Cnt_Ofdm_fail_pre = FalseAlmCnt->Cnt_Ofdm_fail; + FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Ofdm_fail - Cnt_Ofdm_fail_temp; + } + else + FalseAlmCnt->Cnt_Ofdm_fail_pre = FalseAlmCnt->Cnt_Ofdm_fail; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail_pre)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Ofdm_fail_pre=%d\n", Cnt_Ofdm_fail_temp)); + + // Reset FA counter by enable/disable OFDM + if(FalseAlmCnt->Cnt_Ofdm_fail_pre >= 0x7fff) + { + // reset OFDM + ODM_SetBBReg(pDM_Odm, ODM_REG_BB_RX_PATH_11AC, BIT29,0); + ODM_SetBBReg(pDM_Odm, ODM_REG_BB_RX_PATH_11AC, BIT29,1); + FalseAlmCnt->Cnt_Ofdm_fail_pre = 0; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Reset false alarm counter\n")); + } + } +#endif + + // reset OFDM FA coutner + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT17, 1); + ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT17, 0); + + // reset CCK FA counter + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT15, 0); + ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT15, 1); + + // reset CCA counter + ODM_SetBBReg(pDM_Odm, ODM_REG_RST_RPT_11AC, BIT0, 1); + ODM_SetBBReg(pDM_Odm, ODM_REG_RST_RPT_11AC, BIT0, 0); + + CCKenable = ODM_GetBBReg(pDM_Odm, ODM_REG_BB_RX_PATH_11AC, BIT28); + if(CCKenable)//if(*pDM_Odm->pBandType == ODM_BAND_2_4G) + { + FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail + FalseAlmCnt->Cnt_Cck_fail; + FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_CCK_CCA + FalseAlmCnt->Cnt_OFDM_CCA; + } + else + { + FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail; + FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA; + } + + } +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_OFDM_CCA=%d\n", FalseAlmCnt->Cnt_OFDM_CCA)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_CCK_CCA=%d\n", FalseAlmCnt->Cnt_CCK_CCA)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_CCA_all=%d\n", FalseAlmCnt->Cnt_CCA_all)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Cck_fail=%d\n", FalseAlmCnt->Cnt_Cck_fail)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Total False Alarm=%d\n", FalseAlmCnt->Cnt_all)); +} + +//3============================================================ +//3 CCK Packet Detect Threshold +//3============================================================ + +VOID +odm_PauseCCKPacketDetection( + IN PVOID pDM_VOID, + IN ODM_Pause_CCKPD_TYPE PauseType, + IN u1Byte CCKPDThreshold +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + static BOOLEAN bPaused = FALSE; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection()=========>\n")); + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + if(*pDM_DigTable->pbP2pLinkInProgress) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("P2P in progress !!\n")); + return; + } +#endif + + if(!bPaused && (!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) || !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("Return: SupportAbility ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n")); + return; + } + + switch(PauseType) + { + //1 Pause CCK Packet Detection Threshold + case ODM_PAUSE_CCKPD: + //2 Disable DIG + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility & (~ODM_BB_CCK_PD)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("Pause CCK packet detection threshold !!\n")); + + //2 Backup CCK Packet Detection Threshold value + if(!bPaused) + { + pDM_DigTable->CCKPDBackup = pDM_DigTable->CurCCK_CCAThres; + bPaused = TRUE; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("Backup CCK packet detection tgreshold = %d\n", pDM_DigTable->CCKPDBackup)); + + //2 Write new CCK Packet Detection Threshold value + ODM_Write_CCK_CCA_Thres(pDM_Odm, CCKPDThreshold); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("Write new CCK packet detection tgreshold = %d\n", CCKPDThreshold)); + break; + + //1 Resume CCK Packet Detection Threshold + case ODM_RESUME_CCKPD: + if(bPaused) + { + //2 Write backup CCK Packet Detection Threshold value + ODM_Write_CCK_CCA_Thres(pDM_Odm, pDM_DigTable->CCKPDBackup); + bPaused = FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("Write original CCK packet detection tgreshold = %d\n", pDM_DigTable->CCKPDBackup)); + + //2 Enable CCK Packet Detection Threshold + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_CCK_PD); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("Resume CCK packet detection threshold !!\n")); + } + break; + + default: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("Wrong type !!\n")); + break; + } + return; +} + + +VOID +odm_CCKPacketDetectionThresh( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); + u1Byte CurCCK_CCAThres; + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +//modify by Guo.Mingzhi 2011-12-29 + if (pDM_Odm->bDualMacSmartConcurrent == TRUE) +// if (pDM_Odm->bDualMacSmartConcurrent == FALSE) + return; + if(pDM_Odm->bBtHsOperation) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() write 0xcd for BT HS mode!!\n")); + ODM_Write_CCK_CCA_Thres(pDM_Odm, 0xcd); + return; + } +#endif + + if((!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD)) ||(!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() return==========\n")); + return; + } + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(pDM_Odm->ExtLNA) + return; +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() ==========>\n")); + + if(pDM_Odm->bLinked) + { + if(pDM_Odm->RSSI_Min > 25) + CurCCK_CCAThres = 0xcd; + else if((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) + CurCCK_CCAThres = 0x83; + else + { + if(FalseAlmCnt->Cnt_Cck_fail > 1000) + CurCCK_CCAThres = 0x83; + else + CurCCK_CCAThres = 0x40; + } + } + else + { + if(FalseAlmCnt->Cnt_Cck_fail > 1000) + CurCCK_CCAThres = 0x83; + else + CurCCK_CCAThres = 0x40; + } + +#if (RTL8192D_SUPPORT==1) + if((pDM_Odm->SupportICType == ODM_RTL8192D) && (*pDM_Odm->pBandType == ODM_BAND_2_4G)) + ODM_Write_CCK_CCA_Thres_92D(pDM_Odm, CurCCK_CCAThres); + else +#endif + ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() CurCCK_CCAThres = 0x%x\n",CurCCK_CCAThres)); +} + +VOID +ODM_Write_CCK_CCA_Thres( + IN PVOID pDM_VOID, + IN u1Byte CurCCK_CCAThres + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + + if(pDM_DigTable->CurCCK_CCAThres!=CurCCK_CCAThres) //modify by Guo.Mingzhi 2012-01-03 + { + ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA,pDM_Odm), CurCCK_CCAThres); + } + pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; + pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +// <20130108, Kordan> E.g., With LNA used, we make the Rx power smaller to have a better EVM. (Asked by Willis) +VOID +odm_RFEControl( + IN PDM_ODM_T pDM_Odm, + IN u8Byte RSSIVal + ) +{ + PADAPTER Adapter = (PADAPTER)pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + static u1Byte TRSW_HighPwr = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("===> odm_RFEControl, RSSI = %d, TRSW_HighPwr = 0x%X, pHalData->RFEType = %d\n", + RSSIVal, TRSW_HighPwr, pHalData->RFEType )); + + if (pHalData->RFEType == 3) { + + pDM_Odm->RSSI_TRSW = RSSIVal; + + if (pDM_Odm->RSSI_TRSW >= pDM_Odm->RSSI_TRSW_H) + { + TRSW_HighPwr = 1; // Switch to + PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT1|BIT0, 0x1); // Set ANTSW=1/ANTSWB=0 for SW control + PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT9|BIT8, 0x3); // Set ANTSW=1/ANTSWB=0 for SW control + + } + else if (pDM_Odm->RSSI_TRSW <= pDM_Odm->RSSI_TRSW_L) + { + TRSW_HighPwr = 0; // Switched back + PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT1|BIT0, 0x1); // Set ANTSW=1/ANTSWB=0 for SW control + PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT9|BIT8, 0x0); // Set ANTSW=1/ANTSWB=0 for SW control + + } + } + + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("(pDM_Odm->RSSI_TRSW_H, pDM_Odm->RSSI_TRSW_L) = (%d, %d)\n", pDM_Odm->RSSI_TRSW_H, pDM_Odm->RSSI_TRSW_L)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("(RSSIVal, RSSIVal, pDM_Odm->RSSI_TRSW_iso) = (%d, %d, %d)\n", + RSSIVal, pDM_Odm->RSSI_TRSW_iso, pDM_Odm->RSSI_TRSW)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("<=== odm_RFEControl, RSSI = %d, TRSW_HighPwr = 0x%X\n", RSSIVal, TRSW_HighPwr)); +} + +VOID +odm_MPT_DIGWorkItemCallback( + IN PVOID pContext + ) +{ + PADAPTER Adapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + ODM_MPT_DIG(pDM_Odm); +} + +VOID +odm_MPT_DIGCallback( + PRT_TIMER pTimer +) +{ + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + + #if DEV_BUS_TYPE==RT_PCI_INTERFACE + #if USE_WORKITEM + PlatformScheduleWorkItem(&pDM_Odm->MPT_DIGWorkitem); + #else + ODM_MPT_DIG(pDM_Odm); + #endif + #else + PlatformScheduleWorkItem(&pDM_Odm->MPT_DIGWorkitem); + #endif + +} + +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +VOID +odm_MPT_DIGCallback( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if USE_WORKITEM + PlatformScheduleWorkItem(&pDM_Odm->MPT_DIGWorkitem); +#else + ODM_MPT_DIG(pDM_Odm); +#endif +} +#endif + +#if (DM_ODM_SUPPORT_TYPE != ODM_CE) +VOID +odm_MPT_Write_DIG( + IN PVOID pDM_VOID, + IN u1Byte CurIGValue +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + + ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_A,pDM_Odm), CurIGValue); + + if(pDM_Odm->RFType > ODM_1T1R) + ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_B,pDM_Odm), CurIGValue); + + if((pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) && (pDM_Odm->RFType > ODM_2T2R)) + { + ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_C,pDM_Odm), CurIGValue); + ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_D,pDM_Odm), CurIGValue); + } + + pDM_DigTable->CurIGValue = CurIGValue; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("CurIGValue = 0x%x\n", CurIGValue)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("pDM_Odm->RFType = 0x%x\n", pDM_Odm->RFType)); +} + +VOID +ODM_MPT_DIG( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); + u1Byte CurrentIGI = pDM_DigTable->CurIGValue; + u1Byte DIG_Upper = 0x40, DIG_Lower = 0x20; + u4Byte RXOK_cal; + u4Byte RxPWDBAve_final; + u1Byte IGI_A = 0x20, IGI_B = 0x20; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + #if ODM_FIX_2G_DIG + IGI_A = 0x22; + IGI_B = 0x24; + #endif + +#else + if (!(pDM_Odm->priv->pshare->rf_ft_var.mp_specific && pDM_Odm->priv->pshare->mp_dig_on)) + return; + + if (*pDM_Odm->pBandType == ODM_BAND_5G) + DIG_Lower = 0x22; +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("===> ODM_MPT_DIG, pBandType = %d\n", *pDM_Odm->pBandType)); + +#if (ODM_FIX_2G_DIG || (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL))) + if (*pDM_Odm->pBandType == ODM_BAND_5G || (pDM_Odm->SupportICType & ODM_RTL8814A)) // for 5G or 8814 +#else + if (1) // for both 2G/5G +#endif + { + odm_FalseAlarmCounterStatistics(pDM_Odm); + + RXOK_cal = pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM; + RxPWDBAve_final = (RXOK_cal != 0)?pDM_Odm->RxPWDBAve/RXOK_cal:0; + + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK = 0; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM = 0; + pDM_Odm->RxPWDBAve = 0; + pDM_Odm->MPDIG_2G = FALSE; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pDM_Odm->Times_2G = 0; +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("RX OK = %d\n", RXOK_cal)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("RSSI = %d\n", RxPWDBAve_final)); + + if (RXOK_cal >= 70 && RxPWDBAve_final <= 40) + { + if (CurrentIGI > 0x24) + odm_MPT_Write_DIG(pDM_Odm, 0x24); + } + else + { + if(pFalseAlmCnt->Cnt_all > 1000){ + CurrentIGI = CurrentIGI + 8; + } + else if(pFalseAlmCnt->Cnt_all > 200){ + CurrentIGI = CurrentIGI + 4; + } + else if (pFalseAlmCnt->Cnt_all > 50){ + CurrentIGI = CurrentIGI + 2; + } + else if (pFalseAlmCnt->Cnt_all < 2){ + CurrentIGI = CurrentIGI - 2; + } + + if (CurrentIGI < DIG_Lower ){ + CurrentIGI = DIG_Lower; + } + + if(CurrentIGI > DIG_Upper){ + CurrentIGI = DIG_Upper; + } + + odm_MPT_Write_DIG(pDM_Odm, CurrentIGI); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG = 0x%x, Cnt_all = %d, Cnt_Ofdm_fail = %d, Cnt_Cck_fail = %d\n", + CurrentIGI, pFalseAlmCnt->Cnt_all, pFalseAlmCnt->Cnt_Ofdm_fail, pFalseAlmCnt->Cnt_Cck_fail)); + } + } + else + { + if(pDM_Odm->MPDIG_2G == FALSE) + { + if((pDM_Odm->SupportPlatform & ODM_WIN) && !(pDM_Odm->SupportICType & ODM_RTL8814A)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("===> Fix IGI\n")); + ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_A,pDM_Odm), IGI_A); + ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_B,pDM_Odm), IGI_B); + pDM_DigTable->CurIGValue = IGI_B; + } + else + odm_MPT_Write_DIG(pDM_Odm, IGI_A); + } + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pDM_Odm->Times_2G++; + + if (pDM_Odm->Times_2G == 3) +#endif + { + pDM_Odm->MPDIG_2G = TRUE; + } + } + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (pDM_Odm->SupportICType == ODM_RTL8812) + odm_RFEControl(pDM_Odm, RxPWDBAve_final); +#endif + + ODM_SetTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer, 700); +} +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DIG.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DIG.h new file mode 100755 index 000000000000..54e74d781dad --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DIG.h @@ -0,0 +1,309 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMDIG_H__ +#define __PHYDMDIG_H__ + +#define DIG_VERSION "1.1" + +typedef struct _Dynamic_Initial_Gain_Threshold_ +{ + BOOLEAN bStopDIG; // for debug + BOOLEAN bPauseDIG; + BOOLEAN bIgnoreDIG; + BOOLEAN bPSDInProgress; + + u1Byte Dig_Enable_Flag; + u1Byte Dig_Ext_Port_Stage; + + int RssiLowThresh; + int RssiHighThresh; + + u4Byte FALowThresh; + u4Byte FAHighThresh; + + u1Byte CurSTAConnectState; + u1Byte PreSTAConnectState; + u1Byte CurMultiSTAConnectState; + + u1Byte PreIGValue; + u1Byte CurIGValue; + u1Byte BackupIGValue; //MP DIG + u1Byte BT30_CurIGI; + u1Byte IGIBackup; + + s1Byte BackoffVal; + s1Byte BackoffVal_range_max; + s1Byte BackoffVal_range_min; + u1Byte rx_gain_range_max; + u1Byte rx_gain_range_min; + u1Byte Rssi_val_min; + + u1Byte PreCCK_CCAThres; + u1Byte CurCCK_CCAThres; + u1Byte PreCCKPDState; + u1Byte CurCCKPDState; + u1Byte CCKPDBackup; + + u1Byte LargeFAHit; + u1Byte ForbiddenIGI; + u4Byte Recover_cnt; + + u1Byte DIG_Dynamic_MIN_0; + u1Byte DIG_Dynamic_MIN_1; + BOOLEAN bMediaConnect_0; + BOOLEAN bMediaConnect_1; + + u4Byte AntDiv_RSSI_max; + u4Byte RSSI_max; + + u1Byte *pbP2pLinkInProgress; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + BOOLEAN bTpTarget; + BOOLEAN bNoiseEst; + u4Byte TpTrainTH_min; + u1Byte IGIOffset_A; + u1Byte IGIOffset_B; +#endif +}DIG_T,*pDIG_T; + +typedef struct _FALSE_ALARM_STATISTICS{ + u4Byte Cnt_Parity_Fail; + u4Byte Cnt_Rate_Illegal; + u4Byte Cnt_Crc8_fail; + u4Byte Cnt_Mcs_fail; + u4Byte Cnt_Ofdm_fail; + u4Byte Cnt_Ofdm_fail_pre; //For RTL8881A + u4Byte Cnt_Cck_fail; + u4Byte Cnt_all; + u4Byte Cnt_Fast_Fsync; + u4Byte Cnt_SB_Search_fail; + u4Byte Cnt_OFDM_CCA; + u4Byte Cnt_CCK_CCA; + u4Byte Cnt_CCA_all; + u4Byte Cnt_BW_USC; //Gary + u4Byte Cnt_BW_LSC; //Gary +}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS; + +typedef enum tag_Dynamic_Init_Gain_Operation_Type_Definition +{ + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}DM_DIG_OP_E; + +typedef enum tag_ODM_PauseDIG_Type { + ODM_PAUSE_DIG = BIT0, + ODM_RESUME_DIG = BIT1 +} ODM_Pause_DIG_TYPE; + +typedef enum tag_ODM_PauseCCKPD_Type { + ODM_PAUSE_CCKPD = BIT0, + ODM_RESUME_CCKPD = BIT1 +} ODM_Pause_CCKPD_TYPE; + +/* +typedef enum tag_CCK_Packet_Detection_Threshold_Type_Definition +{ + CCK_PD_STAGE_LowRssi = 0, + CCK_PD_STAGE_HighRssi = 1, + CCK_PD_STAGE_MAX = 3, +}DM_CCK_PDTH_E; + +typedef enum tag_DIG_EXT_PORT_ALGO_Definition +{ + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}DM_DIG_EXT_PORT_ALG_E; + +typedef enum tag_DIG_Connect_Definition +{ + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MultiSTA_DISCONNECT = 3, + DIG_MultiSTA_CONNECT = 4, + DIG_CONNECT_MAX +}DM_DIG_CONNECT_E; + + +#define DM_MultiSTA_InitGainChangeNotify(Event) {DM_DigTable.CurMultiSTAConnectState = Event;} + +#define DM_MultiSTA_InitGainChangeNotify_CONNECT(_ADAPTER) \ + DM_MultiSTA_InitGainChangeNotify(DIG_MultiSTA_CONNECT) + +#define DM_MultiSTA_InitGainChangeNotify_DISCONNECT(_ADAPTER) \ + DM_MultiSTA_InitGainChangeNotify(DIG_MultiSTA_DISCONNECT) +*/ +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX_NIC 0x3e +#define DM_DIG_MIN_NIC 0x1e //0x22//0x1c +#define DM_DIG_MAX_OF_MIN_NIC 0x3e + +#define DM_DIG_MAX_AP 0x3e +#define DM_DIG_MIN_AP 0x1c +#define DM_DIG_MAX_OF_MIN 0x2A //0x32 +#define DM_DIG_MIN_AP_DFS 0x20 + +#define DM_DIG_MAX_NIC_HP 0x46 +#define DM_DIG_MIN_NIC_HP 0x2e + +#define DM_DIG_MAX_AP_HP 0x42 +#define DM_DIG_MIN_AP_HP 0x30 + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#define DM_DIG_MAX_AP_COVERAGR 0x26 +#define DM_DIG_MIN_AP_COVERAGE 0x1c +#define DM_DIG_MAX_OF_MIN_COVERAGE 0x22 + +#define DM_DIG_TP_Target_TH0 500 +#define DM_DIG_TP_Target_TH1 1000 +#define DM_DIG_TP_Training_Period 10 +#endif + +//vivi 92c&92d has different definition, 20110504 +//this is for 92c +#if (DM_ODM_SUPPORT_TYPE & ODM_CE) + #ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + #define DM_DIG_FA_TH0 0x80//0x20 + #else + #define DM_DIG_FA_TH0 0x200//0x20 + #endif +#else + #define DM_DIG_FA_TH0 0x200//0x20 +#endif + +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 +//this is for 92d +#define DM_DIG_FA_TH0_92D 0x100 +#define DM_DIG_FA_TH1_92D 0x400 +#define DM_DIG_FA_TH2_92D 0x600 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define DM_DIG_FA_TH0_LPS 4 //-> 4 in lps +#define DM_DIG_FA_TH1_LPS 15 //-> 15 lps +#define DM_DIG_FA_TH2_LPS 30 //-> 30 lps +#define RSSI_OFFSET_DIG 0x05 + +VOID +ODM_ChangeDynamicInitGainThresh( + IN PVOID pDM_VOID, + IN u4Byte DM_Type, + IN u4Byte DM_Value + ); + +VOID +ODM_Write_DIG( + IN PVOID pDM_VOID, + IN u1Byte CurrentIGI + ); + +VOID +odm_PauseDIG( + IN PVOID pDM_VOID, + IN ODM_Pause_DIG_TYPE PauseType, + IN u1Byte IGIValue + ); + +VOID +odm_DIGInit( + IN PVOID pDM_VOID + ); + +VOID +odm_DIG( + IN PVOID pDM_VOID + ); + +VOID +odm_DIGbyRSSI_LPS( + IN PVOID pDM_VOID + ); + +VOID +odm_FalseAlarmCounterStatistics( + IN PVOID pDM_VOID + ); + +VOID +odm_PauseCCKPacketDetection( + IN PVOID pDM_VOID, + IN ODM_Pause_CCKPD_TYPE PauseType, + IN u1Byte CCKPDThreshold + ); + +VOID +odm_CCKPacketDetectionThresh( + IN PVOID pDM_VOID + ); + +VOID +ODM_Write_CCK_CCA_Thres( + IN PVOID pDM_VOID, + IN u1Byte CurCCK_CCAThres + ); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +odm_MPT_DIGCallback( + PRT_TIMER pTimer +); + +VOID +odm_MPT_DIGWorkItemCallback( + IN PVOID pContext + ); + +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +VOID +odm_MPT_DIGCallback( + IN PVOID pDM_VOID +); +#endif + +#if (DM_ODM_SUPPORT_TYPE != ODM_CE) +VOID +ODM_MPT_DIG( + IN PVOID pDM_VOID +); +#endif + + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicBBPowerSaving.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicBBPowerSaving.c new file mode 100755 index 000000000000..a9099ade38a3 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicBBPowerSaving.c @@ -0,0 +1,218 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +VOID +odm_DynamicBBPowerSavingInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPS_T pDM_PSTable = &pDM_Odm->DM_PSTable; + + pDM_PSTable->PreCCAState = CCA_MAX; + pDM_PSTable->CurCCAState = CCA_MAX; + pDM_PSTable->PreRFState = RF_MAX; + pDM_PSTable->CurRFState = RF_MAX; + pDM_PSTable->Rssi_val_min = 0; + pDM_PSTable->initialize = 0; +} + + +VOID +odm_DynamicBBPowerSaving( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + + if (pDM_Odm->SupportICType != ODM_RTL8723A) + return; + if(!(pDM_Odm->SupportAbility & ODM_BB_PWR_SAVE)) + return; + if(!(pDM_Odm->SupportPlatform & (ODM_WIN|ODM_CE))) + return; + + //1 2.Power Saving for 92C + if((pDM_Odm->SupportICType == ODM_RTL8192C) &&(pDM_Odm->RFType == ODM_2T2R)) + { + odm_1R_CCA(pDM_Odm); + } + + // 20100628 Joseph: Turn off BB power save for 88CE because it makesthroughput unstable. + // 20100831 Joseph: Turn ON BB power save again after modifying AGC delay from 900ns ot 600ns. + //1 3.Power Saving for 88C + else + { + ODM_RF_Saving(pDM_Odm, FALSE); + } +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +} + +VOID +odm_1R_CCA( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPS_T pDM_PSTable = &pDM_Odm->DM_PSTable; + + if(pDM_Odm->RSSI_Min!= 0xFF) + { + + if(pDM_PSTable->PreCCAState == CCA_2R) + { + if(pDM_Odm->RSSI_Min >= 35) + pDM_PSTable->CurCCAState = CCA_1R; + else + pDM_PSTable->CurCCAState = CCA_2R; + + } + else{ + if(pDM_Odm->RSSI_Min <= 30) + pDM_PSTable->CurCCAState = CCA_2R; + else + pDM_PSTable->CurCCAState = CCA_1R; + } + } + else{ + pDM_PSTable->CurCCAState=CCA_MAX; + } + + if(pDM_PSTable->PreCCAState != pDM_PSTable->CurCCAState) + { + if(pDM_PSTable->CurCCAState == CCA_1R) + { + if( pDM_Odm->RFType ==ODM_2T2R ) + { + ODM_SetBBReg(pDM_Odm, 0xc04 , bMaskByte0, 0x13); + //PHY_SetBBReg(pAdapter, 0xe70, bMaskByte3, 0x20); + } + else + { + ODM_SetBBReg(pDM_Odm, 0xc04 , bMaskByte0, 0x23); + //PHY_SetBBReg(pAdapter, 0xe70, 0x7fc00000, 0x10c); // Set RegE70[30:22] = 9b'100001100 + } + } + else + { + ODM_SetBBReg(pDM_Odm, 0xc04 , bMaskByte0, 0x33); + //PHY_SetBBReg(pAdapter,0xe70, bMaskByte3, 0x63); + } + pDM_PSTable->PreCCAState = pDM_PSTable->CurCCAState; + } +} + +void +ODM_RF_Saving( + IN PVOID pDM_VOID, + IN u1Byte bForceInNormal + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) + pPS_T pDM_PSTable = &pDM_Odm->DM_PSTable; + u1Byte Rssi_Up_bound = 30 ; + u1Byte Rssi_Low_bound = 25; +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + if(pDM_Odm->PatchID == 40 ) //RT_CID_819x_FUNAI_TV + { + Rssi_Up_bound = 50 ; + Rssi_Low_bound = 45; + } +#endif + if(pDM_PSTable->initialize == 0){ + + pDM_PSTable->Reg874 = (ODM_GetBBReg(pDM_Odm, 0x874, bMaskDWord)&0x1CC000)>>14; + pDM_PSTable->RegC70 = (ODM_GetBBReg(pDM_Odm, 0xc70, bMaskDWord)&BIT3)>>3; + pDM_PSTable->Reg85C = (ODM_GetBBReg(pDM_Odm, 0x85c, bMaskDWord)&0xFF000000)>>24; + pDM_PSTable->RegA74 = (ODM_GetBBReg(pDM_Odm, 0xa74, bMaskDWord)&0xF000)>>12; + //Reg818 = PHY_QueryBBReg(pAdapter, 0x818, bMaskDWord); + pDM_PSTable->initialize = 1; + } + + if(!bForceInNormal) + { + if(pDM_Odm->RSSI_Min != 0xFF) + { + if(pDM_PSTable->PreRFState == RF_Normal) + { + if(pDM_Odm->RSSI_Min >= Rssi_Up_bound) + pDM_PSTable->CurRFState = RF_Save; + else + pDM_PSTable->CurRFState = RF_Normal; + } + else{ + if(pDM_Odm->RSSI_Min <= Rssi_Low_bound) + pDM_PSTable->CurRFState = RF_Normal; + else + pDM_PSTable->CurRFState = RF_Save; + } + } + else + pDM_PSTable->CurRFState=RF_MAX; + } + else + { + pDM_PSTable->CurRFState = RF_Normal; + } + + if(pDM_PSTable->PreRFState != pDM_PSTable->CurRFState) + { + if(pDM_PSTable->CurRFState == RF_Save) + { + // 8723 RSSI report will be wrong. Set 0x874[5]=1 when enter BB power saving mode. + // Suggested by SD3 Yu-Nan. 2011.01.20. + if(pDM_Odm->SupportICType == ODM_RTL8723A) + { + ODM_SetBBReg(pDM_Odm, 0x874 , BIT5, 0x1); //Reg874[5]=1b'1 + } + ODM_SetBBReg(pDM_Odm, 0x874 , 0x1C0000, 0x2); //Reg874[20:18]=3'b010 + ODM_SetBBReg(pDM_Odm, 0xc70, BIT3, 0); //RegC70[3]=1'b0 + ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, 0x63); //Reg85C[31:24]=0x63 + ODM_SetBBReg(pDM_Odm, 0x874, 0xC000, 0x2); //Reg874[15:14]=2'b10 + ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, 0x3); //RegA75[7:4]=0x3 + ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 0x0); //Reg818[28]=1'b0 + ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 0x1); //Reg818[28]=1'b1 + } + else + { + ODM_SetBBReg(pDM_Odm, 0x874 , 0x1CC000, pDM_PSTable->Reg874); + ODM_SetBBReg(pDM_Odm, 0xc70, BIT3, pDM_PSTable->RegC70); + ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, pDM_PSTable->Reg85C); + ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, pDM_PSTable->RegA74); + ODM_SetBBReg(pDM_Odm,0x818, BIT28, 0x0); + + if(pDM_Odm->SupportICType == ODM_RTL8723A) + { + ODM_SetBBReg(pDM_Odm,0x874 , BIT5, 0x0); //Reg874[5]=1b'0 + } + } + pDM_PSTable->PreRFState =pDM_PSTable->CurRFState; + } +#endif +} \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicBBPowerSaving.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicBBPowerSaving.h new file mode 100755 index 000000000000..ef045098afbf --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicBBPowerSaving.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMDYNAMICBBPOWERSAVING_H__ +#define __PHYDMDYNAMICBBPOWERSAVING_H__ + +#define DYNAMIC_BBPWRSAV_VERSION "1.0" + +typedef struct _Dynamic_Power_Saving_ +{ + u1Byte PreCCAState; + u1Byte CurCCAState; + + u1Byte PreRFState; + u1Byte CurRFState; + + int Rssi_val_min; + + u1Byte initialize; + u4Byte Reg874,RegC70,Reg85C,RegA74; + +}PS_T,*pPS_T; + +#define dm_RF_Saving ODM_RF_Saving + +void ODM_RF_Saving( + IN PVOID pDM_VOID, + IN u1Byte bForceInNormal + ); + +VOID +odm_DynamicBBPowerSavingInit( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicBBPowerSaving( + IN PVOID pDM_VOID + ); + +VOID +odm_1R_CCA( + IN PVOID pDM_VOID + ); + +#endif \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicTxPower.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicTxPower.c new file mode 100755 index 000000000000..5a6d2a94f805 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicTxPower.c @@ -0,0 +1,882 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +VOID +odm_DynamicTxPowerInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + #if DEV_BUS_TYPE==RT_USB_INTERFACE + if(RT_GetInterfaceSelection(Adapter) == INTF_SEL1_USB_High_Power) + { + odm_DynamicTxPowerSavePowerIndex(pDM_Odm); + pMgntInfo->bDynamicTxPowerEnable = TRUE; + } + else + #else + //so 92c pci do not need dynamic tx power? vivi check it later + if(IS_HARDWARE_TYPE_8192D(Adapter)) + pMgntInfo->bDynamicTxPowerEnable = TRUE; + else + pMgntInfo->bDynamicTxPowerEnable = FALSE; + #endif + + + pHalData->LastDTPLvl = TxHighPwrLevel_Normal; + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + pdmpriv->bDynamicTxPowerEnable = _FALSE; + + #if (RTL8192C_SUPPORT==1) + #ifdef CONFIG_USB_HCI + + #ifdef CONFIG_INTEL_PROXIM + if((pHalData->BoardType == BOARD_USB_High_PA)||(Adapter->proximity.proxim_support==_TRUE)) + #else + if(pHalData->BoardType == BOARD_USB_High_PA) + #endif + + { + //odm_SavePowerIndex(Adapter); + odm_DynamicTxPowerSavePowerIndex(pDM_Odm); + pdmpriv->bDynamicTxPowerEnable = _TRUE; + } + else + #else + pdmpriv->bDynamicTxPowerEnable = _FALSE; + #endif + #endif + + pdmpriv->LastDTPLvl = TxHighPwrLevel_Normal; + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + +#endif + +} + +VOID +odm_DynamicTxPowerSavePowerIndex( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + u1Byte index; + u4Byte Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + for(index = 0; index< 6; index++) + pHalData->PowerIndex_backup[index] = PlatformEFIORead1Byte(Adapter, Power_Index_REG[index]); +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + for(index = 0; index< 6; index++) + pdmpriv->PowerIndex_backup[index] = rtw_read8(Adapter, Power_Index_REG[index]); +#endif +#endif +} + +VOID +odm_DynamicTxPowerRestorePowerIndex( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + u1Byte index; + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u4Byte Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + for(index = 0; index< 6; index++) + PlatformEFIOWrite1Byte(Adapter, Power_Index_REG[index], pHalData->PowerIndex_backup[index]); +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + struct dm_priv *pdmpriv = &pHalData->dmpriv; + for(index = 0; index< 6; index++) + rtw_write8(Adapter, Power_Index_REG[index], pdmpriv->PowerIndex_backup[index]); +#endif +#endif +} + +VOID +odm_DynamicTxPowerWritePowerIndex( + IN PVOID pDM_VOID, + IN u1Byte Value) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte index; + u4Byte Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + + for(index = 0; index< 6; index++) + //PlatformEFIOWrite1Byte(Adapter, Power_Index_REG[index], Value); + ODM_Write1Byte(pDM_Odm, Power_Index_REG[index], Value); + +} + + +VOID +odm_DynamicTxPower( + IN PVOID pDM_VOID + ) +{ + // + // For AP/ADSL use prtl8192cd_priv + // For CE/NIC use PADAPTER + // + //PADAPTER pAdapter = pDM_Odm->Adapter; +// prtl8192cd_priv priv = pDM_Odm->priv; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if (!(pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR)) + return; + // + // 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate + // at the same time. In the stage2/3, we need to prive universal interface and merge all + // HW dynamic mechanism. + // + switch (pDM_Odm->SupportPlatform) + { + case ODM_WIN: + case ODM_CE: + odm_DynamicTxPowerNIC(pDM_Odm); + break; + case ODM_AP: + odm_DynamicTxPowerAP(pDM_Odm); + break; + + case ODM_ADSL: + //odm_DIGAP(pDM_Odm); + break; + } + + +} + + +VOID +odm_DynamicTxPowerNIC( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (!(pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR)) + return; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + + if(pDM_Odm->SupportICType == ODM_RTL8192C) + { + odm_DynamicTxPower_92C(pDM_Odm); + } + else if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + odm_DynamicTxPower_92D(pDM_Odm); + } + else if (pDM_Odm->SupportICType == ODM_RTL8821) + { +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = GetDefaultMgntInfo(Adapter); + + if (pMgntInfo->RegRspPwr == 1) + { + if(pDM_Odm->RSSI_Min > 60) + { + ODM_SetMACReg(pDM_Odm, ODM_REG_RESP_TX_11AC, BIT20|BIT19|BIT18, 1); // Resp TXAGC offset = -3dB + + } + else if(pDM_Odm->RSSI_Min < 55) + { + ODM_SetMACReg(pDM_Odm, ODM_REG_RESP_TX_11AC, BIT20|BIT19|BIT18, 0); // Resp TXAGC offset = 0dB + } + } +#endif + } +#endif +} + +VOID +odm_DynamicTxPowerAP( + IN PVOID pDM_VOID + + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + +//#if ((RTL8192C_SUPPORT==1) || (RTL8192D_SUPPORT==1) || (RTL8188E_SUPPORT==1) || (RTL8812E_SUPPORT==1)) + + + prtl8192cd_priv priv = pDM_Odm->priv; + s4Byte i; + s2Byte pwr_thd = TX_POWER_NEAR_FIELD_THRESH_AP; + + if(!priv->pshare->rf_ft_var.tx_pwr_ctrl) + return; + +#if ((RTL8812E_SUPPORT==1) || (RTL8881A_SUPPORT==1)) + if (pDM_Odm->SupportICType & (ODM_RTL8812 | ODM_RTL8881A)) + pwr_thd = TX_POWER_NEAR_FIELD_THRESH_8812; +#endif + +#if defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_92C_SUPPORT) + if(CHIP_VER_92X_SERIES(priv)) + { +#ifdef HIGH_POWER_EXT_PA + if(pDM_Odm->ExtPA) + tx_power_control(priv); +#endif + } +#endif + /* + * Check if station is near by to use lower tx power + */ + + if ((priv->up_time % 3) == 0 ) { + int disable_pwr_ctrl = ((pDM_Odm->FalseAlmCnt.Cnt_all > 1000 ) || ((pDM_Odm->FalseAlmCnt.Cnt_all > 300 ) && ((RTL_R8(0xc50) & 0x7f) >= 0x32))) ? 1 : 0; + + for(i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pstat) ) { + if(disable_pwr_ctrl) + pstat->hp_level = 0; + else if ((pstat->hp_level == 0) && (pstat->rssi > pwr_thd)) + pstat->hp_level = 1; + else if ((pstat->hp_level == 1) && (pstat->rssi < (pwr_thd-8))) + pstat->hp_level = 0; + } + } + +#if defined(CONFIG_WLAN_HAL_8192EE) + if (GET_CHIP_VER(priv) == VERSION_8192E) { + if( !disable_pwr_ctrl && (pDM_Odm->RSSI_Min != 0xff) ) { + if(pDM_Odm->RSSI_Min > pwr_thd) + RRSR_power_control_11n(priv, 1 ); + else if(pDM_Odm->RSSI_Min < (pwr_thd-8)) + RRSR_power_control_11n(priv, 0 ); + } else { + RRSR_power_control_11n(priv, 0 ); + } + } +#endif + } +//#endif + +#endif +} + + +VOID +odm_DynamicTxPower_92C( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + s4Byte UndecoratedSmoothedPWDB; + + // 2012/01/12 MH According to Luke's suggestion, only high power will support the feature. + if (pDM_Odm->ExtPA == FALSE) + return; + + // STA not connected and AP not connected + if((!pMgntInfo->bMediaConnect) && + (pHalData->EntryMinUndecoratedSmoothedPWDB == 0)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("Not connected to any \n")); + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + + //the LastDTPlvl should reset when disconnect, + //otherwise the tx power level wouldn't change when disconnect and connect again. + // Maddest 20091220. + pHalData->LastDTPLvl=TxHighPwrLevel_Normal; + return; + } + +#if (INTEL_PROXIMITY_SUPPORT == 1) + // Intel set fixed tx power + if(pMgntInfo->IntelProximityModeInfo.PowerOutput > 0) + { + switch(pMgntInfo->IntelProximityModeInfo.PowerOutput){ + case 1: + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_100; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_100\n")); + break; + case 2: + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_70; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_70\n")); + break; + case 3: + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_50; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_50\n")); + break; + case 4: + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_35; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_35\n")); + break; + case 5: + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_15; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_15\n")); + break; + default: + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_100; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_100\n")); + break; + } + } + else +#endif + { + if( (pMgntInfo->bDynamicTxPowerEnable != TRUE) || + pMgntInfo->IOTAction & HT_IOT_ACT_DISABLE_HIGH_POWER) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + } + else + { + if(pMgntInfo->bMediaConnect) // Default port + { + if(ACTING_AS_AP(Adapter) || ACTING_AS_IBSS(Adapter)) + { + UndecoratedSmoothedPWDB = pHalData->EntryMinUndecoratedSmoothedPWDB; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("AP Client PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + else + { + UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("STA Default Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + } + else // associated entry pwdb + { + UndecoratedSmoothedPWDB = pHalData->EntryMinUndecoratedSmoothedPWDB; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("AP Ext Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + + if(UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL2) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Level2; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x0)\n")); + } + else if((UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL2-3)) && + (UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL1) ) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Level1; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } + else if(UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL1-5)) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_Normal\n")); + } + } + } + if( pHalData->DynamicTxHighPowerLvl != pHalData->LastDTPLvl ) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("PHY_SetTxPowerLevel8192C() Channel = %d \n" , pHalData->CurrentChannel)); + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + if( (pHalData->DynamicTxHighPowerLvl == TxHighPwrLevel_Normal) && + (pHalData->LastDTPLvl == TxHighPwrLevel_Level1 || pHalData->LastDTPLvl == TxHighPwrLevel_Level2)) //TxHighPwrLevel_Normal + odm_DynamicTxPowerRestorePowerIndex(pDM_Odm); + else if(pHalData->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) + odm_DynamicTxPowerWritePowerIndex(pDM_Odm, 0x14); + else if(pHalData->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) + odm_DynamicTxPowerWritePowerIndex(pDM_Odm, 0x10); + } + pHalData->LastDTPLvl = pHalData->DynamicTxHighPowerLvl; + + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + + #if (RTL8192C_SUPPORT==1) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + int UndecoratedSmoothedPWDB; + + if(!pdmpriv->bDynamicTxPowerEnable) + return; + +#ifdef CONFIG_INTEL_PROXIM + if(Adapter->proximity.proxim_on== _TRUE){ + struct proximity_priv *prox_priv=Adapter->proximity.proximity_priv; + // Intel set fixed tx power + printk("\n %s Adapter->proximity.proxim_on=%d prox_priv->proxim_modeinfo->power_output=%d \n",__FUNCTION__,Adapter->proximity.proxim_on,prox_priv->proxim_modeinfo->power_output); + if(prox_priv!=NULL){ + if(prox_priv->proxim_modeinfo->power_output> 0) + { + switch(prox_priv->proxim_modeinfo->power_output) + { + case 1: + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_100; + printk("TxHighPwrLevel_100\n"); + break; + case 2: + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_70; + printk("TxHighPwrLevel_70\n"); + break; + case 3: + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_50; + printk("TxHighPwrLevel_50\n"); + break; + case 4: + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_35; + printk("TxHighPwrLevel_35\n"); + break; + case 5: + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_15; + printk("TxHighPwrLevel_15\n"); + break; + default: + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_100; + printk("TxHighPwrLevel_100\n"); + break; + } + } + } + } + else +#endif + { + // STA not connected and AP not connected + if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) && + (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) + { + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("Not connected to any \n")); + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + + //the LastDTPlvl should reset when disconnect, + //otherwise the tx power level wouldn't change when disconnect and connect again. + // Maddest 20091220. + pdmpriv->LastDTPLvl=TxHighPwrLevel_Normal; + return; + } + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) // Default port + { + #if 0 + //todo: AP Mode + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) + { + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("AP Client PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + else + { + UndecoratedSmoothedPWDB = pdmpriv->UndecoratedSmoothedPWDB; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("STA Default Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + #else + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + #endif + } + else // associated entry pwdb + { + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("AP Ext Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + + if(UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL2) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Level2; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x0)\n")); + } + else if((UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL2-3)) && + (UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL1) ) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Level1; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } + else if(UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL1-5)) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("TxHighPwrLevel_Normal\n")); + } + } + if( (pdmpriv->DynamicTxHighPowerLvl != pdmpriv->LastDTPLvl) ) + { + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Normal) // HP1 -> Normal or HP2 -> Normal + odm_DynamicTxPowerRestorePowerIndex(pDM_Odm); + else if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) + odm_DynamicTxPowerWritePowerIndex(pDM_Odm, 0x14); + else if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) + odm_DynamicTxPowerWritePowerIndex(pDM_Odm, 0x10); + } + pdmpriv->LastDTPLvl = pdmpriv->DynamicTxHighPowerLvl; + #endif +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +} + + +VOID +odm_DynamicTxPower_92D( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + s4Byte UndecoratedSmoothedPWDB; + + PADAPTER BuddyAdapter = Adapter->BuddyAdapter; + BOOLEAN bGetValueFromBuddyAdapter = dm_DualMacGetParameterFromBuddyAdapter(Adapter); + u1Byte HighPowerLvlBackForMac0 = TxHighPwrLevel_Level1; + + // 2012/01/12 MH According to Luke's suggestion, only high power will support the feature. + if (pDM_Odm->ExtPA == FALSE) + return; + + // If dynamic high power is disabled. + if( (pMgntInfo->bDynamicTxPowerEnable != TRUE) || + pMgntInfo->IOTAction & HT_IOT_ACT_DISABLE_HIGH_POWER) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + return; + } + + // STA not connected and AP not connected + if((!pMgntInfo->bMediaConnect) && + (pHalData->EntryMinUndecoratedSmoothedPWDB == 0)) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("Not connected to any \n")); + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + + //the LastDTPlvl should reset when disconnect, + //otherwise the tx power level wouldn't change when disconnect and connect again. + // Maddest 20091220. + pHalData->LastDTPLvl=TxHighPwrLevel_Normal; + return; + } + + if(pMgntInfo->bMediaConnect) // Default port + { + if(ACTING_AS_AP(Adapter) || pMgntInfo->mIbss) + { + UndecoratedSmoothedPWDB = pHalData->EntryMinUndecoratedSmoothedPWDB; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("AP Client PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + else + { + UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("STA Default Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + } + else // associated entry pwdb + { + UndecoratedSmoothedPWDB = pHalData->EntryMinUndecoratedSmoothedPWDB; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("AP Ext Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + + if(IS_HARDWARE_TYPE_8192D(Adapter) && GET_HAL_DATA(Adapter)->CurrentBandType == 1){ + if(UndecoratedSmoothedPWDB >= 0x33) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Level2; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n")); + } + else if((UndecoratedSmoothedPWDB <0x33) && + (UndecoratedSmoothedPWDB >= 0x2b) ) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Level1; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } + else if(UndecoratedSmoothedPWDB < 0x2b) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("5G:TxHighPwrLevel_Normal\n")); + } + + } + else + + { + if(UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL2) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Level1; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x0)\n")); + } + else if((UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL2-3)) && + (UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL1) ) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Level1; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } + else if(UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL1-5)) + { + pHalData->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("TxHighPwrLevel_Normal\n")); + } + + } + +//sherry delete flag 20110517 + if(bGetValueFromBuddyAdapter) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() mac 0 for mac 1 \n")); + if(Adapter->DualMacDMSPControl.bChangeTxHighPowerLvlForAnotherMacOfDMSP) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() change value \n")); + HighPowerLvlBackForMac0 = pHalData->DynamicTxHighPowerLvl; + pHalData->DynamicTxHighPowerLvl = Adapter->DualMacDMSPControl.CurTxHighLvlForAnotherMacOfDMSP; + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + pHalData->DynamicTxHighPowerLvl = HighPowerLvlBackForMac0; + Adapter->DualMacDMSPControl.bChangeTxHighPowerLvlForAnotherMacOfDMSP = FALSE; + } + } + + if( (pHalData->DynamicTxHighPowerLvl != pHalData->LastDTPLvl) ) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("PHY_SetTxPowerLevel8192S() Channel = %d \n" , pHalData->CurrentChannel)); + if(Adapter->DualMacSmartConcurrent == TRUE) + { + if(BuddyAdapter == NULL) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() BuddyAdapter == NULL case \n")); + if(!Adapter->bSlaveOfDMSP) + { + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + } + } + else + { + if(pHalData->MacPhyMode92D == DUALMAC_SINGLEPHY) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() BuddyAdapter DMSP \n")); + if(Adapter->bSlaveOfDMSP) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() bslave case \n")); + BuddyAdapter->DualMacDMSPControl.bChangeTxHighPowerLvlForAnotherMacOfDMSP = TRUE; + BuddyAdapter->DualMacDMSPControl.CurTxHighLvlForAnotherMacOfDMSP = pHalData->DynamicTxHighPowerLvl; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() master case \n")); + if(!bGetValueFromBuddyAdapter) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() mac 0 for mac 0 \n")); + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + } + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_TXPWR,DBG_LOUD,("dm_DynamicTxPower() BuddyAdapter DMDP\n")); + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + } + } + } + else + { + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + } + + } + pHalData->LastDTPLvl = pHalData->DynamicTxHighPowerLvl; +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) +#if (RTL8192D_SUPPORT==1) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DM_ODM_T *podmpriv = &pHalData->odmpriv; + int UndecoratedSmoothedPWDB; + #if (RTL8192D_EASY_SMART_CONCURRENT == 1) + PADAPTER BuddyAdapter = Adapter->BuddyAdapter; + BOOLEAN bGetValueFromBuddyAdapter = DualMacGetParameterFromBuddyAdapter(Adapter); + u8 HighPowerLvlBackForMac0 = TxHighPwrLevel_Level1; + #endif + + // If dynamic high power is disabled. + if( (pdmpriv->bDynamicTxPowerEnable != _TRUE) || + (!(podmpriv->SupportAbility& ODM_BB_DYNAMIC_TXPWR)) ) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + return; + } + + // STA not connected and AP not connected + if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) && + (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) + { + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("Not connected to any \n")); + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + //the LastDTPlvl should reset when disconnect, + //otherwise the tx power level wouldn't change when disconnect and connect again. + // Maddest 20091220. + pdmpriv->LastDTPLvl=TxHighPwrLevel_Normal; + return; + } + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) // Default port + { + #if 0 + //todo: AP Mode + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) + { + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("AP Client PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + else + { + UndecoratedSmoothedPWDB = pdmpriv->UndecoratedSmoothedPWDB; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("STA Default Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + #else + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + #endif + } + else // associated entry pwdb + { + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("AP Ext Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } +#if TX_POWER_FOR_5G_BAND == 1 + if(pHalData->CurrentBandType92D == BAND_ON_5G){ + if(UndecoratedSmoothedPWDB >= 0x33) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Level2; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n")); + } + else if((UndecoratedSmoothedPWDB <0x33) && + (UndecoratedSmoothedPWDB >= 0x2b) ) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Level1; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } + else if(UndecoratedSmoothedPWDB < 0x2b) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("5G:TxHighPwrLevel_Normal\n")); + } + } + else +#endif + { + if(UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL2) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Level2; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x0)\n")); + } + else if((UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL2-3)) && + (UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL1) ) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Level1; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } + else if(UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL1-5)) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("TxHighPwrLevel_Normal\n")); + } + } +#if (RTL8192D_EASY_SMART_CONCURRENT == 1) + if(bGetValueFromBuddyAdapter) + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() mac 0 for mac 1 \n")); + if(Adapter->DualMacDMSPControl.bChangeTxHighPowerLvlForAnotherMacOfDMSP) + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() change value \n")); + HighPowerLvlBackForMac0 = pHalData->DynamicTxHighPowerLvl; + pHalData->DynamicTxHighPowerLvl = Adapter->DualMacDMSPControl.CurTxHighLvlForAnotherMacOfDMSP; + PHY_SetTxPowerLevel8192D(Adapter, pHalData->CurrentChannel); + pHalData->DynamicTxHighPowerLvl = HighPowerLvlBackForMac0; + Adapter->DualMacDMSPControl.bChangeTxHighPowerLvlForAnotherMacOfDMSP = _FALSE; + } + } +#endif + + if( (pdmpriv->DynamicTxHighPowerLvl != pdmpriv->LastDTPLvl) ) + { + //ODM_RT_TRACE(pDM_Odm,COMP_HIPWR, DBG_LOUD, ("PHY_SetTxPowerLevel8192S() Channel = %d \n" , pHalData->CurrentChannel)); +#if (RTL8192D_EASY_SMART_CONCURRENT == 1) + if(BuddyAdapter == NULL) + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() BuddyAdapter == NULL case \n")); + if(!Adapter->bSlaveOfDMSP) + { + PHY_SetTxPowerLevel8192D(Adapter, pHalData->CurrentChannel); + } + } + else + { + if(pHalData->MacPhyMode92D == DUALMAC_SINGLEPHY) + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() BuddyAdapter DMSP \n")); + if(Adapter->bSlaveOfDMSP) + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() bslave case \n")); + BuddyAdapter->DualMacDMSPControl.bChangeTxHighPowerLvlForAnotherMacOfDMSP = _TRUE; + BuddyAdapter->DualMacDMSPControl.CurTxHighLvlForAnotherMacOfDMSP = pHalData->DynamicTxHighPowerLvl; + } + else + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() master case \n")); + if(!bGetValueFromBuddyAdapter) + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() mac 0 for mac 0 \n")); + PHY_SetTxPowerLevel8192D(Adapter, pHalData->CurrentChannel); + } + } + } + else + { + //ODM_RT_TRACE(pDM_Odm,COMP_MLME,DBG_LOUD,("dm_DynamicTxPower() BuddyAdapter DMDP\n")); + PHY_SetTxPowerLevel8192D(Adapter, pHalData->CurrentChannel); + } + } +#else + PHY_SetTxPowerLevel8192D(Adapter, pHalData->CurrentChannel); +#endif + } + pdmpriv->LastDTPLvl = pdmpriv->DynamicTxHighPowerLvl; +#endif +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicTxPower.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicTxPower.h new file mode 100755 index 000000000000..508cd31277d3 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_DynamicTxPower.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMDYNAMICTXPOWER_H__ +#define __PHYDMDYNAMICTXPOWER_H__ + +#define DYNAMIC_TXPWR_VERSION "1.0" + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define TX_POWER_NEAR_FIELD_THRESH_AP 0x3F +#define TX_POWER_NEAR_FIELD_THRESH_8812 60 + +#define TxHighPwrLevel_Normal 0 +#define TxHighPwrLevel_Level1 1 +#define TxHighPwrLevel_Level2 2 +#define TxHighPwrLevel_BT1 3 +#define TxHighPwrLevel_BT2 4 +#define TxHighPwrLevel_15 5 +#define TxHighPwrLevel_35 6 +#define TxHighPwrLevel_50 7 +#define TxHighPwrLevel_70 8 +#define TxHighPwrLevel_100 9 + +VOID +odm_DynamicTxPowerInit( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerRestorePowerIndex( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerNIC( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +odm_DynamicTxPowerSavePowerIndex( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerWritePowerIndex( + IN PVOID pDM_VOID, + IN u1Byte Value); + +VOID +odm_DynamicTxPower_92C( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPower_92D( + IN PVOID pDM_VOID + ); +#endif + +VOID +odm_DynamicTxPower( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerAP( + IN PVOID pDM_VOID + ); + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_EdcaTurboCheck.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_EdcaTurboCheck.c new file mode 100755 index 000000000000..479300050b4d --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_EdcaTurboCheck.c @@ -0,0 +1,1915 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +VOID +ODM_EdcaTurboInit( + IN PVOID pDM_VOID) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if ((DM_ODM_SUPPORT_TYPE == ODM_AP)||(DM_ODM_SUPPORT_TYPE==ODM_ADSL)) + odm_EdcaParaInit(pDM_Odm); +#elif (DM_ODM_SUPPORT_TYPE==ODM_WIN) + PADAPTER Adapter = NULL; + HAL_DATA_TYPE *pHalData = NULL; + + if(pDM_Odm->Adapter==NULL) { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("EdcaTurboInit fail!!!\n")); + return; + } + + Adapter=pDM_Odm->Adapter; + pHalData=GET_HAL_DATA(Adapter); + + pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = FALSE; + pDM_Odm->DM_EDCA_Table.bIsCurRDLState = FALSE; + pHalData->bIsAnyNonBEPkts = FALSE; + +#elif(DM_ODM_SUPPORT_TYPE==ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = FALSE; + pDM_Odm->DM_EDCA_Table.bIsCurRDLState = FALSE; + Adapter->recvpriv.bIsAnyNonBEPkts =FALSE; + +#endif + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Orginial VO PARAM: 0x%x\n",ODM_Read4Byte(pDM_Odm,ODM_EDCA_VO_PARAM))); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Orginial VI PARAM: 0x%x\n",ODM_Read4Byte(pDM_Odm,ODM_EDCA_VI_PARAM))); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Orginial BE PARAM: 0x%x\n",ODM_Read4Byte(pDM_Odm,ODM_EDCA_BE_PARAM))); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Orginial BK PARAM: 0x%x\n",ODM_Read4Byte(pDM_Odm,ODM_EDCA_BK_PARAM))); + + +} // ODM_InitEdcaTurbo + +VOID +odm_EdcaTurboCheck( + IN PVOID pDM_VOID + ) +{ + // + // For AP/ADSL use prtl8192cd_priv + // For CE/NIC use PADAPTER + // + + // + // 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate + // at the same time. In the stage2/3, we need to prive universal interface and merge all + // HW dynamic mechanism. + // + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("odm_EdcaTurboCheck========================>\n")); + + if(!(pDM_Odm->SupportAbility& ODM_MAC_EDCA_TURBO )) + return; + + switch (pDM_Odm->SupportPlatform) + { + case ODM_WIN: + +#if(DM_ODM_SUPPORT_TYPE==ODM_WIN) + odm_EdcaTurboCheckMP(pDM_Odm); +#endif + break; + + case ODM_CE: +#if(DM_ODM_SUPPORT_TYPE==ODM_CE) + odm_EdcaTurboCheckCE(pDM_Odm); +#endif + break; + + case ODM_AP: + case ODM_ADSL: + +#if ((DM_ODM_SUPPORT_TYPE == ODM_AP)||(DM_ODM_SUPPORT_TYPE==ODM_ADSL)) + odm_IotEngine(pDM_Odm); +#endif + break; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("<========================odm_EdcaTurboCheck\n")); + +} // odm_CheckEdcaTurbo + +#if(DM_ODM_SUPPORT_TYPE==ODM_CE) + + +VOID +odm_EdcaTurboCheckCE( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + u32 EDCA_BE_UL = 0x5ea42b;//Parameter suggested by Scott //edca_setting_UL[pMgntInfo->IOTPeer]; + u32 EDCA_BE_DL = 0x5ea42b;//Parameter suggested by Scott //edca_setting_DL[pMgntInfo->IOTPeer]; + u32 ICType=pDM_Odm->SupportICType; + u32 IOTPeer=0; + u8 WirelessMode=0xFF; //invalid value + u32 trafficIndex; + u32 edca_param; + u64 cur_tx_bytes = 0; + u64 cur_rx_bytes = 0; + u8 bbtchange = _FALSE; + u8 bBiasOnRx = _FALSE; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct recv_priv *precvpriv = &(Adapter->recvpriv); + struct registry_priv *pregpriv = &Adapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pDM_Odm->bLinked != _TRUE) + { + precvpriv->bIsAnyNonBEPkts = _FALSE; + return; + } + + if ((pregpriv->wifi_spec == 1) )//|| (pmlmeinfo->HT_enable == 0)) + { + precvpriv->bIsAnyNonBEPkts = _FALSE; + return; + } + + if(pDM_Odm->pWirelessMode!=NULL) + WirelessMode=*(pDM_Odm->pWirelessMode); + + IOTPeer = pmlmeinfo->assoc_AP_vendor; + + if (IOTPeer >= HT_IOT_PEER_MAX) + { + precvpriv->bIsAnyNonBEPkts = _FALSE; + return; + } + + if( (pDM_Odm->SupportICType == ODM_RTL8192C) || + (pDM_Odm->SupportICType == ODM_RTL8723A) || + (pDM_Odm->SupportICType == ODM_RTL8188E)) + { + if((IOTPeer == HT_IOT_PEER_RALINK)||(IOTPeer == HT_IOT_PEER_ATHEROS)) + bBiasOnRx = _TRUE; + } + + // Check if the status needs to be changed. + if((bbtchange) || (!precvpriv->bIsAnyNonBEPkts) ) + { + cur_tx_bytes = pdvobjpriv->traffic_stat.cur_tx_bytes; + cur_rx_bytes = pdvobjpriv->traffic_stat.cur_rx_bytes; + + //traffic, TX or RX + if(bBiasOnRx) + { + if (cur_tx_bytes > (cur_rx_bytes << 2)) + { // Uplink TP is present. + trafficIndex = UP_LINK; + } + else + { // Balance TP is present. + trafficIndex = DOWN_LINK; + } + } + else + { + if (cur_rx_bytes > (cur_tx_bytes << 2)) + { // Downlink TP is present. + trafficIndex = DOWN_LINK; + } + else + { // Balance TP is present. + trafficIndex = UP_LINK; + } + } + + //if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) || (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) + { + if(ICType==ODM_RTL8192D) + { + // Single PHY + if(pDM_Odm->RFType==ODM_2T2R) + { + EDCA_BE_UL = 0x60a42b; //0x5ea42b; + EDCA_BE_DL = 0x60a42b; //0x5ea42b; + } + else + { + EDCA_BE_UL = 0x6ea42b; + EDCA_BE_DL = 0x6ea42b; + } + } + else + { + if(pDM_Odm->SupportInterface==ODM_ITRF_PCIE) { + if((ICType==ODM_RTL8192C)&&(pDM_Odm->RFType==ODM_2T2R)) { + EDCA_BE_UL = 0x60a42b; + EDCA_BE_DL = 0x60a42b; + } + else + { + EDCA_BE_UL = 0x6ea42b; + EDCA_BE_DL = 0x6ea42b; + } + } + } + + //92D txop can't be set to 0x3e for cisco1250 + if((ICType!=ODM_RTL8192D) && (IOTPeer== HT_IOT_PEER_CISCO) &&(WirelessMode==ODM_WM_N24G)) + { + EDCA_BE_DL = edca_setting_DL[IOTPeer]; + EDCA_BE_UL = edca_setting_UL[IOTPeer]; + } + //merge from 92s_92c_merge temp brunch v2445 20120215 + else if((IOTPeer == HT_IOT_PEER_CISCO) &&((WirelessMode==ODM_WM_G)||(WirelessMode==(ODM_WM_B|ODM_WM_G))||(WirelessMode==ODM_WM_A)||(WirelessMode==ODM_WM_B))) + { + EDCA_BE_DL = edca_setting_DL_GMode[IOTPeer]; + } + else if((IOTPeer== HT_IOT_PEER_AIRGO )&& ((WirelessMode==ODM_WM_G)||(WirelessMode==ODM_WM_A))) + { + EDCA_BE_DL = 0xa630; + } + else if(IOTPeer == HT_IOT_PEER_MARVELL) + { + EDCA_BE_DL = edca_setting_DL[IOTPeer]; + EDCA_BE_UL = edca_setting_UL[IOTPeer]; + } + else if(IOTPeer == HT_IOT_PEER_ATHEROS) + { + // Set DL EDCA for Atheros peer to 0x3ea42b. Suggested by SD3 Wilson for ASUS TP issue. + EDCA_BE_DL = edca_setting_DL[IOTPeer]; + } + + if((ICType==ODM_RTL8812)||(ICType==ODM_RTL8821)||(ICType==ODM_RTL8192E)) //add 8812AU/8812AE + { + EDCA_BE_UL = 0x5ea42b; + EDCA_BE_DL = 0x5ea42b; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("8812A: EDCA_BE_UL=0x%x EDCA_BE_DL =0x%x",EDCA_BE_UL,EDCA_BE_DL)); + } + + if (trafficIndex == DOWN_LINK) + edca_param = EDCA_BE_DL; + else + edca_param = EDCA_BE_UL; + + rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param); + + pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex; + } + + pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = _TRUE; + } + else + { + // + // Turn Off EDCA turbo here. + // Restore original EDCA according to the declaration of AP. + // + if(pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) + { + rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE); + pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = _FALSE; + } + } + +} + + +#elif(DM_ODM_SUPPORT_TYPE==ODM_WIN) +VOID +odm_EdcaTurboCheckMP( + IN PVOID pDM_VOID + ) +{ + + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + PADAPTER pDefaultAdapter = GetDefaultAdapter(Adapter); + PADAPTER pExtAdapter = GetFirstExtAdapter(Adapter);//NULL; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos; + //[Win7 Count Tx/Rx statistic for Extension Port] odm_CheckEdcaTurbo's Adapter is always Default. 2009.08.20, by Bohn + u8Byte Ext_curTxOkCnt = 0; + u8Byte Ext_curRxOkCnt = 0; + //For future Win7 Enable Default Port to modify AMPDU size dynamically, 2009.08.20, Bohn. + u1Byte TwoPortStatus = (u1Byte)TWO_PORT_STATUS__WITHOUT_ANY_ASSOCIATE; + + // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. + u8Byte curTxOkCnt = 0; + u8Byte curRxOkCnt = 0; + u4Byte EDCA_BE_UL = 0x5ea42b;//Parameter suggested by Scott //edca_setting_UL[pMgntInfo->IOTPeer]; + u4Byte EDCA_BE_DL = 0x5ea42b;//Parameter suggested by Scott //edca_setting_DL[pMgntInfo->IOTPeer]; + u4Byte EDCA_BE = 0x5ea42b; + u1Byte IOTPeer=0; + BOOLEAN *pbIsCurRDLState=NULL; + BOOLEAN bLastIsCurRDLState=FALSE; + BOOLEAN bBiasOnRx=FALSE; + BOOLEAN bEdcaTurboOn=FALSE; + u1Byte TxRate = 0xFF; + u8Byte value64; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("odm_EdcaTurboCheckMP========================>")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Orginial BE PARAM: 0x%x\n",ODM_Read4Byte(pDM_Odm,ODM_EDCA_BE_PARAM))); + +////=============================== +////list paramter for different platform +////=============================== + bLastIsCurRDLState=pDM_Odm->DM_EDCA_Table.bIsCurRDLState; + pbIsCurRDLState=&(pDM_Odm->DM_EDCA_Table.bIsCurRDLState); + + //2012/09/14 MH Add + if (pMgntInfo->NumNonBePkt > pMgntInfo->RegEdcaThresh && !Adapter->MgntInfo.bWiFiConfg) + pHalData->bIsAnyNonBEPkts = TRUE; + + pMgntInfo->NumNonBePkt = 0; + + // Caculate TX/RX TP: + //curTxOkCnt = Adapter->TxStats.NumTxBytesUnicast - pMgntInfo->lastTxOkCnt; + //curRxOkCnt = Adapter->RxStats.NumRxBytesUnicast - pMgntInfo->lastRxOkCnt; + curTxOkCnt = Adapter->TxStats.NumTxBytesUnicast - pDM_Odm->lastTxOkCnt; + curRxOkCnt = Adapter->RxStats.NumRxBytesUnicast - pDM_Odm->lastRxOkCnt; + pDM_Odm->lastTxOkCnt = Adapter->TxStats.NumTxBytesUnicast; + pDM_Odm->lastRxOkCnt = Adapter->RxStats.NumRxBytesUnicast; + + if(pExtAdapter == NULL) + pExtAdapter = pDefaultAdapter; + + Ext_curTxOkCnt = pExtAdapter->TxStats.NumTxBytesUnicast - pMgntInfo->Ext_lastTxOkCnt; + Ext_curRxOkCnt = pExtAdapter->RxStats.NumRxBytesUnicast - pMgntInfo->Ext_lastRxOkCnt; + GetTwoPortSharedResource(Adapter,TWO_PORT_SHARED_OBJECT__STATUS,NULL,&TwoPortStatus); + //For future Win7 Enable Default Port to modify AMPDU size dynamically, 2009.08.20, Bohn. + if(TwoPortStatus == TWO_PORT_STATUS__EXTENSION_ONLY) + { + curTxOkCnt = Ext_curTxOkCnt ; + curRxOkCnt = Ext_curRxOkCnt ; + } + // + IOTPeer=pMgntInfo->IOTPeer; + bBiasOnRx=(pMgntInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX)?TRUE:FALSE; + bEdcaTurboOn=((!pHalData->bIsAnyNonBEPkts))?TRUE:FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("bIsAnyNonBEPkts : 0x%lx \n",pHalData->bIsAnyNonBEPkts)); + + +////=============================== +////check if edca turbo is disabled +////=============================== + if(odm_IsEdcaTurboDisable(pDM_Odm)) + { + pHalData->bIsAnyNonBEPkts = FALSE; + pMgntInfo->lastTxOkCnt = Adapter->TxStats.NumTxBytesUnicast; + pMgntInfo->lastRxOkCnt = Adapter->RxStats.NumRxBytesUnicast; + pMgntInfo->Ext_lastTxOkCnt = pExtAdapter->TxStats.NumTxBytesUnicast; + pMgntInfo->Ext_lastRxOkCnt = pExtAdapter->RxStats.NumRxBytesUnicast; + + } + +////=============================== +////remove iot case out +////=============================== + ODM_EdcaParaSelByIot(pDM_Odm, &EDCA_BE_UL, &EDCA_BE_DL); + + +////=============================== +////Check if the status needs to be changed. +////=============================== + if(bEdcaTurboOn) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",bEdcaTurboOn,bBiasOnRx)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("curTxOkCnt : 0x%lx \n",curTxOkCnt)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("curRxOkCnt : 0x%lx \n",curRxOkCnt)); + if(bBiasOnRx) + odm_EdcaChooseTrafficIdx(pDM_Odm,curTxOkCnt, curRxOkCnt, TRUE, pbIsCurRDLState); + else + odm_EdcaChooseTrafficIdx(pDM_Odm,curTxOkCnt, curRxOkCnt, FALSE, pbIsCurRDLState); + +//modify by Guo.Mingzhi 2011-12-29 + EDCA_BE=((*pbIsCurRDLState)==TRUE)?EDCA_BE_DL:EDCA_BE_UL; + if(IS_HARDWARE_TYPE_8821U(Adapter)) + { + if(pMgntInfo->RegTxDutyEnable) + { + //2013.01.23 LukeLee: debug for 8811AU thermal issue (reduce Tx duty cycle) + if(!pMgntInfo->ForcedDataRate) //auto rate + { + if(pDM_Odm->TxRate != 0xFF) + TxRate = Adapter->HalFunc.GetHwRateFromMRateHandler(pDM_Odm->TxRate); + } + else //force rate + { + TxRate = (u1Byte) pMgntInfo->ForcedDataRate; + } + + value64 = (curRxOkCnt<<2); + if(curTxOkCnt < value64) //Downlink + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + else //Uplink + { + //DbgPrint("pDM_Odm->RFCalibrateInfo.ThermalValue = 0x%X\n", pDM_Odm->RFCalibrateInfo.ThermalValue); + //if(pDM_Odm->RFCalibrateInfo.ThermalValue < pHalData->EEPROMThermalMeter) + if((pDM_Odm->RFCalibrateInfo.ThermalValue < 0x2c) || (*pDM_Odm->pBandType == BAND_ON_2_4G)) + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + else + { + switch (TxRate) + { + case MGN_VHT1SS_MCS6: + case MGN_VHT1SS_MCS5: + case MGN_MCS6: + case MGN_MCS5: + case MGN_48M: + case MGN_54M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0x1ea42b); + break; + case MGN_VHT1SS_MCS4: + case MGN_MCS4: + case MGN_36M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa42b); + break; + case MGN_VHT1SS_MCS3: + case MGN_MCS3: + case MGN_24M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa47f); + break; + case MGN_VHT1SS_MCS2: + case MGN_MCS2: + case MGN_18M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa57f); + break; + case MGN_VHT1SS_MCS1: + case MGN_MCS1: + case MGN_9M: + case MGN_12M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa77f); + break; + case MGN_VHT1SS_MCS0: + case MGN_MCS0: + case MGN_6M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa87f); + break; + default: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + break; + } + } + } + } + else + { + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + } + + } + else if (IS_HARDWARE_TYPE_8812AU(Adapter)){ + if(pMgntInfo->RegTxDutyEnable) + { + //2013.07.26 Wilson: debug for 8812AU thermal issue (reduce Tx duty cycle) + // it;s the same issue as 8811AU + if(!pMgntInfo->ForcedDataRate) //auto rate + { + if(pDM_Odm->TxRate != 0xFF) + TxRate = Adapter->HalFunc.GetHwRateFromMRateHandler(pDM_Odm->TxRate); + } + else //force rate + { + TxRate = (u1Byte) pMgntInfo->ForcedDataRate; + } + + value64 = (curRxOkCnt<<2); + if(curTxOkCnt < value64) //Downlink + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + else //Uplink + { + //DbgPrint("pDM_Odm->RFCalibrateInfo.ThermalValue = 0x%X\n", pDM_Odm->RFCalibrateInfo.ThermalValue); + //if(pDM_Odm->RFCalibrateInfo.ThermalValue < pHalData->EEPROMThermalMeter) + if((pDM_Odm->RFCalibrateInfo.ThermalValue < 0x2c) || (*pDM_Odm->pBandType == BAND_ON_2_4G)) + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + else + { + switch (TxRate) + { + case MGN_VHT2SS_MCS9: + case MGN_VHT1SS_MCS9: + case MGN_VHT1SS_MCS8: + case MGN_MCS15: + case MGN_MCS7: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0x1ea44f); + case MGN_VHT2SS_MCS8: + case MGN_VHT1SS_MCS7: + case MGN_MCS14: + case MGN_MCS6: + case MGN_54M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa44f); + case MGN_VHT2SS_MCS7: + case MGN_VHT2SS_MCS6: + case MGN_VHT1SS_MCS6: + case MGN_VHT1SS_MCS5: + case MGN_MCS13: + case MGN_MCS5: + case MGN_48M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa630); + break; + case MGN_VHT2SS_MCS5: + case MGN_VHT2SS_MCS4: + case MGN_VHT1SS_MCS4: + case MGN_VHT1SS_MCS3: + case MGN_MCS12: + case MGN_MCS4: + case MGN_MCS3: + case MGN_36M: + case MGN_24M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa730); + break; + case MGN_VHT2SS_MCS3: + case MGN_VHT2SS_MCS2: + case MGN_VHT2SS_MCS1: + case MGN_VHT1SS_MCS2: + case MGN_VHT1SS_MCS1: + case MGN_MCS11: + case MGN_MCS10: + case MGN_MCS9: + case MGN_MCS2: + case MGN_MCS1: + case MGN_18M: + case MGN_12M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa830); + break; + case MGN_VHT2SS_MCS0: + case MGN_VHT1SS_MCS0: + case MGN_MCS0: + case MGN_MCS8: + case MGN_9M: + case MGN_6M: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,0xa87f); + break; + default: + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + break; + } + } + } + } + else + { + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + } + } + else + ODM_Write4Byte(pDM_Odm,ODM_EDCA_BE_PARAM,EDCA_BE); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("EDCA Turbo on: EDCA_BE:0x%lx\n",EDCA_BE)); + + pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = TRUE; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("EDCA_BE_DL : 0x%lx EDCA_BE_UL : 0x%lx EDCA_BE : 0x%lx \n",EDCA_BE_DL,EDCA_BE_UL,EDCA_BE)); + + } + else + { + // Turn Off EDCA turbo here. + // Restore original EDCA according to the declaration of AP. + if(pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) + { + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, GET_WMM_PARAM_ELE_SINGLE_AC_PARAM(pStaQos->WMMParamEle, AC0_BE) ); + + pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Restore EDCA BE: 0x%lx \n",pDM_Odm->WMMEDCA_BE)); + + } + } + +} + + +//check if edca turbo is disabled +BOOLEAN +odm_IsEdcaTurboDisable( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + u4Byte IOTPeer=pMgntInfo->IOTPeer; + + if(pDM_Odm->bBtDisableEdcaTurbo) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD, ("EdcaTurboDisable for BT!!\n")); + return TRUE; + } + + if((!(pDM_Odm->SupportAbility& ODM_MAC_EDCA_TURBO ))|| + (pDM_Odm->bWIFITest)|| + (IOTPeer>= HT_IOT_PEER_MAX)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD, ("EdcaTurboDisable\n")); + return TRUE; + } + + + // 1. We do not turn on EDCA turbo mode for some AP that has IOT issue + // 2. User may disable EDCA Turbo mode with OID settings. + if(pMgntInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO){ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD, ("IOTAction:EdcaTurboDisable\n")); + return TRUE; + } + + return FALSE; + + +} + +//add iot case here: for MP/CE +VOID +ODM_EdcaParaSelByIot( + IN PVOID pDM_VOID, + OUT u4Byte *EDCA_BE_UL, + OUT u4Byte *EDCA_BE_DL + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u4Byte IOTPeer=0; + u4Byte ICType=pDM_Odm->SupportICType; + u1Byte WirelessMode=0xFF; //invalid value + u4Byte RFType=pDM_Odm->RFType; + u4Byte IOTPeerSubType=0; + + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + u1Byte TwoPortStatus = (u1Byte)TWO_PORT_STATUS__WITHOUT_ANY_ASSOCIATE; + + if(pDM_Odm->pWirelessMode!=NULL) + WirelessMode=*(pDM_Odm->pWirelessMode); + +/////////////////////////////////////////////////////////// +////list paramter for different platform + + IOTPeer=pMgntInfo->IOTPeer; + IOTPeerSubType=pMgntInfo->IOTPeerSubtype; + GetTwoPortSharedResource(Adapter,TWO_PORT_SHARED_OBJECT__STATUS,NULL,&TwoPortStatus); + + + if(ICType==ODM_RTL8192D) + { + // Single PHY + if(pDM_Odm->RFType==ODM_2T2R) + { + (*EDCA_BE_UL) = 0x60a42b; //0x5ea42b; + (*EDCA_BE_DL) = 0x60a42b; //0x5ea42b; + + } + else + { + (*EDCA_BE_UL) = 0x6ea42b; + (*EDCA_BE_DL) = 0x6ea42b; + } + + } +////============================ +/// IOT case for MP +////============================ + + else + { + + if(pDM_Odm->SupportInterface==ODM_ITRF_PCIE){ + if((ICType==ODM_RTL8192C)&&(pDM_Odm->RFType==ODM_2T2R)) { + (*EDCA_BE_UL) = 0x60a42b; + (*EDCA_BE_DL) = 0x60a42b; + } + else + { + (*EDCA_BE_UL) = 0x6ea42b; + (*EDCA_BE_DL) = 0x6ea42b; + } + } + } + + if(TwoPortStatus == TWO_PORT_STATUS__EXTENSION_ONLY) + { + (*EDCA_BE_UL) = 0x5ea42b;//Parameter suggested by Scott //edca_setting_UL[ExtAdapter->MgntInfo.IOTPeer]; + (*EDCA_BE_DL) = 0x5ea42b;//Parameter suggested by Scott //edca_setting_DL[ExtAdapter->MgntInfo.IOTPeer]; + } + + #if (INTEL_PROXIMITY_SUPPORT == 1) + if(pMgntInfo->IntelClassModeInfo.bEnableCA == TRUE) + { + (*EDCA_BE_UL) = (*EDCA_BE_DL) = 0xa44f; + } + else + #endif + { + if((pMgntInfo->IOTAction & (HT_IOT_ACT_FORCED_ENABLE_BE_TXOP|HT_IOT_ACT_AMSDU_ENABLE))) + {// To check whether we shall force turn on TXOP configuration. + if(!((*EDCA_BE_UL) & 0xffff0000)) + (*EDCA_BE_UL) |= 0x005e0000; // Force TxOP limit to 0x005e for UL. + if(!((*EDCA_BE_DL) & 0xffff0000)) + (*EDCA_BE_DL) |= 0x005e0000; // Force TxOP limit to 0x005e for DL. + } + + //92D txop can't be set to 0x3e for cisco1250 + if((ICType!=ODM_RTL8192D) && (IOTPeer== HT_IOT_PEER_CISCO) &&(WirelessMode==ODM_WM_N24G)) + { + (*EDCA_BE_DL) = edca_setting_DL[IOTPeer]; + (*EDCA_BE_UL) = edca_setting_UL[IOTPeer]; + } + //merge from 92s_92c_merge temp brunch v2445 20120215 + else if((IOTPeer == HT_IOT_PEER_CISCO) &&((WirelessMode==ODM_WM_G)||(WirelessMode==(ODM_WM_B|ODM_WM_G))||(WirelessMode==ODM_WM_A)||(WirelessMode==ODM_WM_B))) + { + (*EDCA_BE_DL) = edca_setting_DL_GMode[IOTPeer]; + } + else if((IOTPeer== HT_IOT_PEER_AIRGO )&& ((WirelessMode==ODM_WM_G)||(WirelessMode==ODM_WM_A))) + { + (*EDCA_BE_DL) = 0xa630; + } + + else if(IOTPeer == HT_IOT_PEER_MARVELL) + { + (*EDCA_BE_DL) = edca_setting_DL[IOTPeer]; + (*EDCA_BE_UL) = edca_setting_UL[IOTPeer]; + } + else if(IOTPeer == HT_IOT_PEER_ATHEROS) + { + // Set DL EDCA for Atheros peer to 0x3ea42b. Suggested by SD3 Wilson for ASUS TP issue. + if(WirelessMode==ODM_WM_G) + (*EDCA_BE_DL) = edca_setting_DL_GMode[IOTPeer]; + else + (*EDCA_BE_DL) = edca_setting_DL[IOTPeer]; + + if(ICType == ODM_RTL8821) + (*EDCA_BE_DL) = 0x5ea630; + + } + } + + if((ICType == ODM_RTL8192D)&&(IOTPeerSubType == HT_IOT_PEER_LINKSYS_E4200_V1)&&((WirelessMode==ODM_WM_N5G))) + { + (*EDCA_BE_DL) = 0x432b; + (*EDCA_BE_UL) = 0x432b; + } + + + + if((ICType==ODM_RTL8812)||(ICType==ODM_RTL8192E)) //add 8812AU/8812AE + { + (*EDCA_BE_UL) = 0x5ea42b; + (*EDCA_BE_DL) = 0x5ea42b; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("8812A: EDCA_BE_UL=0x%lx EDCA_BE_DL =0x%lx",(*EDCA_BE_UL),(*EDCA_BE_DL))); + } + + // Revised for Atheros DIR-655 IOT issue to improve down link TP, added by Roger, 2013.03.22. + if((ICType == ODM_RTL8723A) && (IOTPeerSubType== HT_IOT_PEER_ATHEROS_DIR655) && + (pMgntInfo->dot11CurrentChannelNumber == 6)) + { + (*EDCA_BE_DL) = 0xa92b; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Special: EDCA_BE_UL=0x%lx EDCA_BE_DL =0x%lx",(*EDCA_BE_UL),(*EDCA_BE_DL))); + +} + + +VOID +odm_EdcaChooseTrafficIdx( + IN PVOID pDM_VOID, + IN u8Byte cur_tx_bytes, + IN u8Byte cur_rx_bytes, + IN BOOLEAN bBiasOnRx, + OUT BOOLEAN *pbIsCurRDLState + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if(bBiasOnRx) + { + + if(cur_tx_bytes>(cur_rx_bytes*4)) + { + *pbIsCurRDLState=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Uplink Traffic\n ")); + + } + else + { + *pbIsCurRDLState=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Balance Traffic\n")); + + } + } + else + { + if(cur_rx_bytes>(cur_tx_bytes*4)) + { + *pbIsCurRDLState=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Downlink Traffic\n")); + + } + else + { + *pbIsCurRDLState=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("Balance Traffic\n")); + } + } + + return ; +} + +#endif + +#if((DM_ODM_SUPPORT_TYPE==ODM_AP)||(DM_ODM_SUPPORT_TYPE==ODM_ADSL)) + +void odm_EdcaParaInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + prtl8192cd_priv priv = pDM_Odm->priv; + int mode=priv->pmib->dot11BssType.net_work_type; + + static unsigned int slot_time, sifs_time; + struct ParaRecord EDCA[4]; + + memset(EDCA, 0, 4*sizeof(struct ParaRecord)); + + sifs_time = 10; + slot_time = 20; + + if (mode & (ODM_WM_N24G|ODM_WM_N5G)) + sifs_time = 16; + + if (mode & (ODM_WM_N24G|ODM_WM_N5G| ODM_WM_G|ODM_WM_A)) + slot_time = 9; + + +#ifdef RTK_AC_SUPPORT //for 11ac logo, edit aifs time for cca test cases + if(AC_SIGMA_MODE != AC_SIGMA_NONE) + sifs_time = 10; +#endif + + +#if((defined(RTL_MANUAL_EDCA))&&(DM_ODM_SUPPORT_TYPE==ODM_AP)) + if( priv->pmib->dot11QosEntry.ManualEDCA ) { + if( OPMODE & WIFI_AP_STATE ) + memcpy(EDCA, priv->pmib->dot11QosEntry.AP_manualEDCA, 4*sizeof(struct ParaRecord)); + else + memcpy(EDCA, priv->pmib->dot11QosEntry.STA_manualEDCA, 4*sizeof(struct ParaRecord)); + + #ifdef WIFI_WMM + if (QOS_ENABLE) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VI_PARAM, (EDCA[VI].TXOPlimit<< 16) | (EDCA[VI].ECWmax<< 12) | (EDCA[VI].ECWmin<< 8) | (sifs_time + EDCA[VI].AIFSN* slot_time)); + else + #endif + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VI_PARAM, (EDCA[BE].TXOPlimit<< 16) | (EDCA[BE].ECWmax<< 12) | (EDCA[BE].ECWmin<< 8) | (sifs_time + EDCA[VI].AIFSN* slot_time)); + + }else + #endif //RTL_MANUAL_EDCA + { + + if(OPMODE & WIFI_AP_STATE) + { + memcpy(EDCA, rtl_ap_EDCA, 2*sizeof(struct ParaRecord)); + + if(mode & (ODM_WM_A|ODM_WM_G|ODM_WM_N24G|ODM_WM_N5G)) + memcpy(&EDCA[VI], &rtl_ap_EDCA[VI_AG], 2*sizeof(struct ParaRecord)); + else + memcpy(&EDCA[VI], &rtl_ap_EDCA[VI], 2*sizeof(struct ParaRecord)); + } + else + { + memcpy(EDCA, rtl_sta_EDCA, 2*sizeof(struct ParaRecord)); + + if(mode & (ODM_WM_A|ODM_WM_G|ODM_WM_N24G|ODM_WM_N5G)) + memcpy(&EDCA[VI], &rtl_sta_EDCA[VI_AG], 2*sizeof(struct ParaRecord)); + else + memcpy(&EDCA[VI], &rtl_sta_EDCA[VI], 2*sizeof(struct ParaRecord)); + } + + #ifdef WIFI_WMM + if (QOS_ENABLE) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VI_PARAM, (EDCA[VI].TXOPlimit<< 16) | (EDCA[VI].ECWmax<< 12) | (EDCA[VI].ECWmin<< 8) | (sifs_time + EDCA[VI].AIFSN* slot_time)); + else + #endif + +#if (DM_ODM_SUPPORT_TYPE==ODM_AP) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VI_PARAM, (EDCA[BK].ECWmax<< 12) | (EDCA[BK].ECWmin<< 8) | (sifs_time + EDCA[VI].AIFSN* slot_time)); +#elif(DM_ODM_SUPPORT_TYPE==ODM_ADSL) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VI_PARAM, (EDCA[BK].ECWmax<< 12) | (EDCA[BK].ECWmin<< 8) | (sifs_time + 2* slot_time)); +#endif + + + } + + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VO_PARAM, (EDCA[VO].TXOPlimit<< 16) | (EDCA[VO].ECWmax<< 12) | (EDCA[VO].ECWmin<< 8) | (sifs_time + EDCA[VO].AIFSN* slot_time)); + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (EDCA[BE].TXOPlimit<< 16) | (EDCA[BE].ECWmax<< 12) | (EDCA[BE].ECWmin<< 8) | (sifs_time + EDCA[BE].AIFSN* slot_time)); + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BK_PARAM, (EDCA[BK].TXOPlimit<< 16) | (EDCA[BK].ECWmax<< 12) | (EDCA[BK].ECWmin<< 8) | (sifs_time + EDCA[BK].AIFSN* slot_time)); + +#if defined(RTK_AC_SUPPORT) && defined(RTL_MANUAL_EDCA) //for 11ac logo, make BK worse to seperate with BE. + if((AC_SIGMA_MODE != AC_SIGMA_NONE) && (priv->pmib->dot11QosEntry.ManualEDCA)) + { + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BK_PARAM, (EDCA[BK].TXOPlimit<< 16) | (EDCA[BK].ECWmax<< 12) | (EDCA[BK].ECWmin<< 8) | 0xa4 ); + } +#endif + +// ODM_Write1Byte(pDM_Odm,ACMHWCTRL, 0x00); + + priv->pshare->iot_mode_enable = 0; +#if(DM_ODM_SUPPORT_TYPE==ODM_AP) + if (priv->pshare->rf_ft_var.wifi_beq_iot) + priv->pshare->iot_mode_VI_exist = 0; + + #ifdef WMM_VIBE_PRI + priv->pshare->iot_mode_BE_exist = 0; + #endif + +#ifdef WMM_BEBK_PRI + priv->pshare->iot_mode_BK_exist = 0; +#endif + + #ifdef LOW_TP_TXOP + priv->pshare->BE_cwmax_enhance = 0; + #endif + +#elif (DM_ODM_SUPPORT_TYPE==ODM_ADSL) + priv->pshare->iot_mode_BE_exist = 0; +#endif + priv->pshare->iot_mode_VO_exist = 0; +} + +BOOLEAN +ODM_ChooseIotMainSTA( + IN PVOID pDM_VOID, + IN PSTA_INFO_T pstat + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + prtl8192cd_priv priv = pDM_Odm->priv; + BOOLEAN bhighTP_found_pstat=FALSE; + + if ((GET_ROOT(priv)->up_time % 2) == 0) { + unsigned int tx_2s_avg = 0; + unsigned int rx_2s_avg = 0; + int i=0, aggReady=0; + unsigned long total_sum = (priv->pshare->current_tx_bytes+priv->pshare->current_rx_bytes); + int assoc_num = GET_ROOT(priv)->assoc_num; +#ifdef MBSSID + if (GET_ROOT(priv)->pmib->miscEntry.vap_enable){ + for (i=0; ipvap_priv[i]-> assoc_num; + } +#endif +#ifdef UNIVERSAL_REPEATER + if (IS_DRV_OPEN(GET_VXD_PRIV(GET_ROOT(priv)))) + assoc_num += GET_VXD_PRIV(GET_ROOT(priv))-> assoc_num; +#endif +#ifdef WDS + if(GET_ROOT(priv)->pmib->dot11WdsInfo.wdsEnabled) + assoc_num ++; +#endif + + + pstat->current_tx_bytes += pstat->tx_byte_cnt; + pstat->current_rx_bytes += pstat->rx_byte_cnt; + + if (total_sum != 0) { + if (total_sum <= 1000000) { + tx_2s_avg = (unsigned int)((pstat->current_tx_bytes*100) / total_sum); + rx_2s_avg = (unsigned int)((pstat->current_rx_bytes*100) / total_sum); + } else { + tx_2s_avg = (unsigned int)(pstat->current_tx_bytes / (total_sum / 100)); + rx_2s_avg = (unsigned int)(pstat->current_rx_bytes / (total_sum / 100)); + } + + } + +#if(DM_ODM_SUPPORT_TYPE==ODM_ADSL) + if (pstat->ht_cap_len) { + if ((tx_2s_avg + rx_2s_avg) >=25 ) {//50// + + priv->pshare->highTP_found_pstat = pstat; + bhighTP_found_pstat=TRUE; + } + } +#elif(DM_ODM_SUPPORT_TYPE==ODM_AP) + for(i=0; i<8; i++) + aggReady += (pstat->ADDBA_ready[i]); + + if ((pstat->ht_cap_len && ( +#ifdef SUPPORT_TX_AMSDU + AMSDU_ENABLE || +#endif + aggReady)) || (pstat->IOTPeer==HT_IOT_PEER_INTEL)) + { + if ((assoc_num==1) || (tx_2s_avg + rx_2s_avg >= 25)) { + priv->pshare->highTP_found_pstat = pstat; + } + + #ifdef CLIENT_MODE + if (OPMODE & WIFI_STATION_STATE) { + if ((tx_2s_avg + rx_2s_avg) >= 20) + priv->pshare->highTP_found_pstat = pstat; + } + #endif + } +#endif + } + else { + pstat->current_tx_bytes = pstat->tx_byte_cnt; + pstat->current_rx_bytes = pstat->rx_byte_cnt; + } + + return bhighTP_found_pstat; +} + + +#ifdef WIFI_WMM +VOID +ODM_IotEdcaSwitch( + IN PVOID pDM_VOID, + IN unsigned char enable + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + prtl8192cd_priv priv = pDM_Odm->priv; + int mode=priv->pmib->dot11BssType.net_work_type; + unsigned int slot_time = 20, sifs_time = 10, BE_TXOP = 47, VI_TXOP = 94; + unsigned int vi_cw_max = 4, vi_cw_min = 3, vi_aifs; +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + u32 be_edca, vi_edca; + u16 disable_cfe; +#endif + +#if (DM_ODM_SUPPORT_TYPE==ODM_AP) + if (!(!priv->pmib->dot11OperationEntry.wifi_specific || + ((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific)) + #ifdef CLIENT_MODE + || ((OPMODE & WIFI_STATION_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific)) + #endif + )) + return; +#endif + +#ifdef RTK_AC_SUPPORT //for 11ac logo, do not dynamic switch edca + if(AC_SIGMA_MODE != AC_SIGMA_NONE) + return; +#endif + + if ((mode & (ODM_WM_N24G|ODM_WM_N5G)) && (priv->pshare->ht_sta_num + #ifdef WDS + || ((OPMODE & WIFI_AP_STATE) && priv->pmib->dot11WdsInfo.wdsEnabled && priv->pmib->dot11WdsInfo.wdsNum) + #endif + )) + sifs_time = 16; + + if (mode & (ODM_WM_N24G|ODM_WM_N5G|ODM_WM_G|ODM_WM_A)) { + slot_time = 9; + } + else + { + BE_TXOP = 94; + VI_TXOP = 188; + } + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + vi_edca = -1; + disable_cfe = -1; +#endif + +#if (DM_ODM_SUPPORT_TYPE==ODM_ADSL) + if (priv->pshare->iot_mode_VO_exist) { + // to separate AC_VI and AC_BE to avoid using the same EDCA settings + if (priv->pshare->iot_mode_BE_exist) { + vi_cw_max = 5; + vi_cw_min = 3; + } else { + vi_cw_max = 6; + vi_cw_min = 4; + } + } + vi_aifs = (sifs_time + ((OPMODE & WIFI_AP_STATE)?1:2) * slot_time); + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + vi_edca = ((VI_TXOP*(1-priv->pshare->iot_mode_VO_exist)) << 16)| (vi_cw_max << 12) | (vi_cw_min << 8) | vi_aifs; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VI_PARAM, ((VI_TXOP*(1-priv->pshare->iot_mode_VO_exist)) << 16)| (vi_cw_max << 12) | (vi_cw_min << 8) | vi_aifs); +#endif + +#elif (DM_ODM_SUPPORT_TYPE==ODM_AP) + if ((OPMODE & WIFI_AP_STATE) && priv->pmib->dot11OperationEntry.wifi_specific) { + if (priv->pshare->iot_mode_VO_exist) { + #ifdef WMM_VIBE_PRI + if (priv->pshare->iot_mode_BE_exist) + { + vi_cw_max = 5; + vi_cw_min = 3; + vi_aifs = (sifs_time + ((OPMODE & WIFI_AP_STATE)?1:2) * slot_time); + } + else + #endif + { + vi_cw_max = 6; + vi_cw_min = 4; + vi_aifs = 0x2b; + } + } + else { + vi_aifs = (sifs_time + ((OPMODE & WIFI_AP_STATE)?1:2) * slot_time); + } + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + vi_edca = ((VI_TXOP*(1-priv->pshare->iot_mode_VO_exist)) << 16) + | (vi_cw_max << 12) | (vi_cw_min << 8) | vi_aifs; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_VI_PARAM, ((VI_TXOP*(1-priv->pshare->iot_mode_VO_exist)) << 16) + | (vi_cw_max << 12) | (vi_cw_min << 8) | vi_aifs); +#endif + + #ifdef WMM_BEBK_PRI + #ifdef CONFIG_RTL_88E_SUPPORT + if ((GET_CHIP_VER(priv) == VERSION_8188E) && priv->pshare->iot_mode_BK_exist) { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (10 << 12) | (6 << 8) | 0x4f; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BK_PARAM, (10 << 12) | (6 << 8) | 0x4f); +#endif + } + #endif + #endif +#if defined(CONFIG_WLAN_HAL_8881A) + if (GET_CHIP_VER(priv) == VERSION_8881A) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BK_PARAM, 0xa64f); +#endif + } +#endif + + + +#if (DM_ODM_SUPPORT_TYPE==ODM_AP) + if (priv->pshare->rf_ft_var.wifi_beq_iot && priv->pshare->iot_mode_VI_exist) { +#if defined(CONFIG_RTL_88E_SUPPORT) || defined(CONFIG_RTL_8812_SUPPORT) + if (GET_CHIP_VER(priv) == VERSION_8188E || GET_CHIP_VER(priv) == VERSION_8812E) { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (10 << 12) | (6 << 8) | 0x4f; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (10 << 12) | (6 << 8) | 0x4f); +#endif + } + else +#endif + { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (10 << 12) | (4 << 8) | 0x4f; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (10 << 12) | (4 << 8) | 0x4f); +#endif + } + } else if(!enable) +#elif(DM_ODM_SUPPORT_TYPE==ODM_ADSL) + if(!enable) //if iot is disable ,maintain original BEQ PARAM +#endif + { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (((OPMODE & WIFI_AP_STATE)?6:10) << 12) | (4 << 8) + | (sifs_time + 3 * slot_time); + disable_cfe = 1; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (((OPMODE & WIFI_AP_STATE)?6:10) << 12) | (4 << 8) + | (sifs_time + 3 * slot_time)); +#endif +#ifdef CONFIG_PCI_HCI +// ODM_Write2Byte(pDM_Odm, RD_CTRL, ODM_Read2Byte(pDM_Odm, RD_CTRL) | (DIS_TXOP_CFE)); +#endif + } + else + { + int txop; + unsigned int cw_max; +#ifdef LOW_TP_TXOP + unsigned int txop_close; +#endif + + #if((DM_ODM_SUPPORT_TYPE==ODM_AP)&&(defined LOW_TP_TXOP)) + cw_max = ((priv->pshare->BE_cwmax_enhance) ? 10 : 6); + txop_close = ((priv->pshare->rf_ft_var.low_tp_txop && priv->pshare->rf_ft_var.low_tp_txop_close) ? 1 : 0); + + if(priv->pshare->txop_enlarge == 0xe) //if intel case + txop = (txop_close ? 0 : (BE_TXOP*2)); + else //if other case + txop = (txop_close ? 0: (BE_TXOP*priv->pshare->txop_enlarge)); + #else + cw_max=6; + if((priv->pshare->txop_enlarge==0xe)||(priv->pshare->txop_enlarge==0xd)) + txop=BE_TXOP*2; + else + txop=BE_TXOP*priv->pshare->txop_enlarge; + + #endif + + if (priv->pshare->ht_sta_num + #ifdef WDS + || ((OPMODE & WIFI_AP_STATE) && (mode & (ODM_WM_N24G|ODM_WM_N5G)) && + priv->pmib->dot11WdsInfo.wdsEnabled && priv->pmib->dot11WdsInfo.wdsNum) + #endif + ) + { + + if (priv->pshare->txop_enlarge == 0xe) { + // is intel client, use a different edca value + //ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (txop<< 16) | (cw_max<< 12) | (4 << 8) | 0x1f); + if (pDM_Odm->RFType==ODM_1T1R) { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (txop << 16) | (5 << 12) | (3 << 8) | 0x1f; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (txop << 16) | (5 << 12) | (3 << 8) | 0x1f); +#endif + } + else { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (txop << 16) | (8 << 12) | (5 << 8) | 0x1f; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (txop << 16) | (8 << 12) | (5 << 8) | 0x1f); +#endif + } + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + disable_cfe = 0; +#endif +#ifdef CONFIG_PCI_HCI +// ODM_Write2Byte(pDM_Odm, RD_CTRL, ODM_Read2Byte(pDM_Odm, RD_CTRL) & ~(DIS_TXOP_CFE)); +#endif + priv->pshare->txop_enlarge = 2; + } +#if(DM_ODM_SUPPORT_TYPE==ODM_AP) + #ifndef LOW_TP_TXOP + else if (priv->pshare->txop_enlarge == 0xd) { + // is intel ralink, use a different edca value +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (txop << 16) | (6 << 12) | (5 << 8) | 0x2b; +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (txop << 16) | (6 << 12) | (5 << 8) | 0x2b); +#endif + priv->pshare->txop_enlarge = 2; + } + #endif +#endif + else + { +// if (txop == 0) { +//#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) +// disable_cfe = 1; +//#endif +//#ifdef CONFIG_PCI_HCI +// ODM_Write2Byte(pDM_Odm, RD_CTRL, ODM_Read2Byte(pDM_Odm, RD_CTRL) | (DIS_TXOP_CFE)); +//#endif +// } + + if (pDM_Odm->RFType==ODM_2T2R) { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (txop << 16) | (cw_max << 12) | (4 << 8) | (sifs_time + 3 * slot_time); +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (txop << 16) | + (cw_max << 12) | (4 << 8) | (sifs_time + 3 * slot_time)); +#endif + } + else + #if(DM_ODM_SUPPORT_TYPE==ODM_AP)&&(defined LOW_TP_TXOP) + { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (txop << 16) | + (((priv->pshare->BE_cwmax_enhance) ? 10 : 5) << 12) | (3 << 8) | (sifs_time + 2 * slot_time); +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (txop << 16) | + (((priv->pshare->BE_cwmax_enhance) ? 10 : 5) << 12) | (3 << 8) | (sifs_time + 2 * slot_time)); +#endif + } + #else + { + PSTA_INFO_T pstat = priv->pshare->highTP_found_pstat; + if ((GET_CHIP_VER(priv)==VERSION_8881A) && pstat && (pstat->IOTPeer == HT_IOT_PEER_HTC)) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, 0x642b); + else { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (txop << 16) | (5 << 12) | (3 << 8) | (sifs_time + 2 * slot_time); + #else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (txop << 16) | + (5 << 12) | (3 << 8) | (sifs_time + 2 * slot_time)); +#endif + } + } + #endif + } + } + else + { + #if((DM_ODM_SUPPORT_TYPE==ODM_AP)&&(defined LOW_TP_TXOP)) +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (BE_TXOP << 16) | (cw_max << 12) | (4 << 8) | (sifs_time + 3 * slot_time); +#else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (BE_TXOP << 16) | (cw_max << 12) | (4 << 8) | (sifs_time + 3 * slot_time)); +#endif + #else + #if defined(CONFIG_RTL_8196D) || defined(CONFIG_RTL_8197DL) || defined(CONFIG_RTL_8196E) || (defined(CONFIG_RTL_8197D) && !defined(CONFIG_PORT0_EXT_GIGA)) +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (BE_TXOP*2 << 16) | (cw_max << 12) | (5 << 8) | (sifs_time + 3 * slot_time); + #else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (BE_TXOP*2 << 16) | (cw_max << 12) | (5 << 8) | (sifs_time + 3 * slot_time)); +#endif + #else +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + be_edca = (BE_TXOP*2 << 16) | (cw_max << 12) | (4 << 8) | (sifs_time + 3 * slot_time); + #else + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (BE_TXOP*2 << 16) | (cw_max << 12) | (4 << 8) | (sifs_time + 3 * slot_time)); + #endif + #endif +/* + if (priv->pshare->txop_enlarge == 0xe) { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + disable_cfe = 0; +#endif + #ifdef CONFIG_PCI_HCI + ODM_Write2Byte(pDM_Odm, RD_CTRL, ODM_Read2Byte(pDM_Odm, RD_CTRL) & ~(DIS_TXOP_CFE)); + #endif + } else { +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + disable_cfe = 1; +#endif + #ifdef CONFIG_PCI_HCI + ODM_Write2Byte(pDM_Odm, RD_CTRL, ODM_Read2Byte(pDM_Odm, RD_CTRL) | (DIS_TXOP_CFE)); + #endif + } +*/ + #endif + } + + } + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + notify_IOT_EDCA_switch(priv, be_edca, vi_edca, disable_cfe); +#endif +} +#endif + +VOID +odm_IotEngine( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + struct rtl8192cd_priv *priv=pDM_Odm->priv; + PSTA_INFO_T pstat = NULL; + u4Byte i; + +#ifdef WIFI_WMM + unsigned int switch_turbo = 0, avg_tp; +#endif +//////////////////////////////////////////////////////// +// if EDCA Turbo function is not supported or Manual EDCA Setting +// then return +//////////////////////////////////////////////////////// + if(!(pDM_Odm->SupportAbility&ODM_MAC_EDCA_TURBO)){ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("ODM_MAC_EDCA_TURBO NOT SUPPORTED\n")); + return; + } + +#if((DM_ODM_SUPPORT_TYPE==ODM_AP)&& defined(RTL_MANUAL_EDCA) && defined(WIFI_WMM)) + if(priv->pmib->dot11QosEntry.ManualEDCA){ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("ODM_MAC_EDCA_TURBO OFF: MANUAL SETTING\n")); + return ; + } +#endif + +#if !(DM_ODM_SUPPORT_TYPE &ODM_AP) + ////////////////////////////////////////////////////// + //find high TP STA every 2s +////////////////////////////////////////////////////// + if ((GET_ROOT(priv)->up_time % 2) == 0) + priv->pshare->highTP_found_pstat==NULL; + +#if 0 + phead = &priv->asoc_list; + plist = phead->next; + while(plist != phead) { + pstat = list_entry(plist, struct stat_info, asoc_list); + + if(ODM_ChooseIotMainSTA(pDM_Odm, pstat)); //find the correct station + break; + if (plist == plist->next) //the last plist + break; + plist = plist->next; + }; +#endif + + //find highTP STA + for(i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pstat) && (ODM_ChooseIotMainSTA(pDM_Odm, pstat))) //find the correct station + break; + } + + ////////////////////////////////////////////////////// + //if highTP STA is not found, then return + ////////////////////////////////////////////////////// + if(priv->pshare->highTP_found_pstat==NULL) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("ODM_MAC_EDCA_TURBO OFF: NO HT STA FOUND\n")); + return; + } +#endif + + pstat=priv->pshare->highTP_found_pstat; + if(pstat) { + if((pstat->tx_avarage + pstat->rx_avarage) < (1<<17)) // 1M bps + pstat = NULL; + } + +#ifdef WIFI_WMM + if (QOS_ENABLE) { + if (!priv->pmib->dot11OperationEntry.wifi_specific + #if(DM_ODM_SUPPORT_TYPE==ODM_AP) + ||((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific)) + #elif(DM_ODM_SUPPORT_TYPE==ODM_ADSL) + || (priv->pmib->dot11OperationEntry.wifi_specific == 2) + #endif + ) { + if (priv->pshare->iot_mode_enable && + ((priv->pshare->phw->VO_pkt_count > 50) || + (priv->pshare->phw->VI_pkt_count > 50) || + (priv->pshare->phw->BK_pkt_count > 50))) { + priv->pshare->iot_mode_enable = 0; + switch_turbo++; +#ifdef CONFIG_WLAN_HAL_8881A + if (GET_CHIP_VER(priv) == VERSION_8881A) { + RTL_W32(0x460, 0x03086666); + } +#endif //CONFIG_WLAN_HAL_8881A + } else if ((!priv->pshare->iot_mode_enable) && + ((priv->pshare->phw->VO_pkt_count < 50) && + (priv->pshare->phw->VI_pkt_count < 50) && + (priv->pshare->phw->BK_pkt_count < 50))) { + priv->pshare->iot_mode_enable++; + switch_turbo++; +//#ifdef CONFIG_WLAN_HAL_8881A +#if 0 + if (GET_CHIP_VER(priv) == VERSION_8881A) { + if (get_bonding_type_8881A()==BOND_8881AB) { + RTL_W32(0x460, 0x03086666); + } + else { + RTL_W32(0x460, 0x0320ffff); + } + } +#endif //CONFIG_WLAN_HAL_8881A + } + } + + + #if(DM_ODM_SUPPORT_TYPE==ODM_AP) + if ((OPMODE & WIFI_AP_STATE) && priv->pmib->dot11OperationEntry.wifi_specific) + #elif (DM_ODM_SUPPORT_TYPE==ODM_ADSL) + if (priv->pmib->dot11OperationEntry.wifi_specific) + #endif + { + if (!priv->pshare->iot_mode_VO_exist && (priv->pshare->phw->VO_pkt_count > 50)) { + priv->pshare->iot_mode_VO_exist++; + switch_turbo++; + } else if (priv->pshare->iot_mode_VO_exist && (priv->pshare->phw->VO_pkt_count < 50)) { + priv->pshare->iot_mode_VO_exist = 0; + switch_turbo++; + } +#if((DM_ODM_SUPPORT_TYPE==ODM_ADSL)||((DM_ODM_SUPPORT_TYPE==ODM_AP)&&(defined WMM_VIBE_PRI))) + if (priv->pshare->iot_mode_VO_exist) { + //printk("[%s %d] BE_pkt_count=%d\n", __FUNCTION__, __LINE__, priv->pshare->phw->BE_pkt_count); + if (!priv->pshare->iot_mode_BE_exist && (priv->pshare->phw->BE_pkt_count > 250)) { + priv->pshare->iot_mode_BE_exist++; + switch_turbo++; + } else if (priv->pshare->iot_mode_BE_exist && (priv->pshare->phw->BE_pkt_count < 250)) { + priv->pshare->iot_mode_BE_exist = 0; + switch_turbo++; + } + } +#endif + +#if((DM_ODM_SUPPORT_TYPE==ODM_ADSL)||((DM_ODM_SUPPORT_TYPE==ODM_AP)&&(defined WMM_BEBK_PRI))) + if (priv->pshare->phw->BE_pkt_count) { + //printk("[%s %d] BK_pkt_count=%d\n", __FUNCTION__, __LINE__, priv->pshare->phw->BK_pkt_count); + if (!priv->pshare->iot_mode_BK_exist && (priv->pshare->phw->BK_pkt_count > 250)) { + priv->pshare->iot_mode_BK_exist++; + switch_turbo++; + } else if (priv->pshare->iot_mode_BK_exist && (priv->pshare->phw->BK_pkt_count < 250)) { + priv->pshare->iot_mode_BK_exist = 0; + switch_turbo++; + } + } +#endif + +#if (DM_ODM_SUPPORT_TYPE==ODM_AP) + if (priv->pshare->rf_ft_var.wifi_beq_iot) + { + if (!priv->pshare->iot_mode_VI_exist && (priv->pshare->phw->VI_rx_pkt_count > 50)) { + priv->pshare->iot_mode_VI_exist++; + switch_turbo++; + } else if (priv->pshare->iot_mode_VI_exist && (priv->pshare->phw->VI_rx_pkt_count < 50)) { + priv->pshare->iot_mode_VI_exist = 0; + switch_turbo++; + } + } +#endif + + } + else if (!pstat || pstat->rssi < priv->pshare->rf_ft_var.txop_enlarge_lower) { + if (priv->pshare->txop_enlarge) { + priv->pshare->txop_enlarge = 0; + if (priv->pshare->iot_mode_enable) + switch_turbo++; + } + } + +#if(defined(CLIENT_MODE) && (DM_ODM_SUPPORT_TYPE==ODM_AP)) + if ((OPMODE & WIFI_STATION_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific)) + { + if (priv->pshare->iot_mode_enable && + (((priv->pshare->phw->VO_pkt_count > 50) || + (priv->pshare->phw->VI_pkt_count > 50) || + (priv->pshare->phw->BK_pkt_count > 50)) || + (pstat && (!pstat->ADDBA_ready[0]) & (!pstat->ADDBA_ready[3])))) + { + priv->pshare->iot_mode_enable = 0; + switch_turbo++; + } + else if ((!priv->pshare->iot_mode_enable) && + (((priv->pshare->phw->VO_pkt_count < 50) && + (priv->pshare->phw->VI_pkt_count < 50) && + (priv->pshare->phw->BK_pkt_count < 50)) && + (pstat && (pstat->ADDBA_ready[0] | pstat->ADDBA_ready[3])))) + { + priv->pshare->iot_mode_enable++; + switch_turbo++; + } + } +#endif + + priv->pshare->phw->VO_pkt_count = 0; + priv->pshare->phw->VI_pkt_count = 0; + priv->pshare->phw->BK_pkt_count = 0; + + #if((DM_ODM_SUPPORT_TYPE==ODM_ADSL)||((DM_ODM_SUPPORT_TYPE==ODM_AP)&&(defined WMM_VIBE_PRI))) + priv->pshare->phw->BE_pkt_count = 0; + #endif + + #if(DM_ODM_SUPPORT_TYPE==ODM_AP) + if (priv->pshare->rf_ft_var.wifi_beq_iot) + priv->pshare->phw->VI_rx_pkt_count = 0; + #endif + + } +#endif + + if ((priv->up_time % 2) == 0) { + /* + * decide EDCA content for different chip vendor + */ +#ifdef WIFI_WMM + #if(DM_ODM_SUPPORT_TYPE==ODM_ADSL) + if (QOS_ENABLE && (!priv->pmib->dot11OperationEntry.wifi_specific || (priv->pmib->dot11OperationEntry.wifi_specific == 2) + + #elif(DM_ODM_SUPPORT_TYPE==ODM_AP) + if (QOS_ENABLE && (!priv->pmib->dot11OperationEntry.wifi_specific || + ((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific == 2)) + #ifdef CLIENT_MODE + || ((OPMODE & WIFI_STATION_STATE) && (priv->pmib->dot11OperationEntry.wifi_specific == 2)) + #endif + #endif + )) + + { + + if (pstat && pstat->rssi >= priv->pshare->rf_ft_var.txop_enlarge_upper) { +#ifdef LOW_TP_TXOP + if (pstat->IOTPeer==HT_IOT_PEER_INTEL) + { + if (priv->pshare->txop_enlarge != 0xe) + { + priv->pshare->txop_enlarge = 0xe; + + if (priv->pshare->iot_mode_enable) + switch_turbo++; + } + } + else if (priv->pshare->txop_enlarge != 2) + { + priv->pshare->txop_enlarge = 2; + if (priv->pshare->iot_mode_enable) + switch_turbo++; + } +#else + if (priv->pshare->txop_enlarge != 2) + { + if (pstat->IOTPeer==HT_IOT_PEER_INTEL) + priv->pshare->txop_enlarge = 0xe; + else if (pstat->IOTPeer==HT_IOT_PEER_RALINK) + priv->pshare->txop_enlarge = 0xd; + else if (pstat->IOTPeer==HT_IOT_PEER_HTC) + priv->pshare->txop_enlarge = 0; + else + priv->pshare->txop_enlarge = 2; + + if (priv->pshare->iot_mode_enable) + switch_turbo++; + } +#endif + } + else if (!pstat || pstat->rssi < priv->pshare->rf_ft_var.txop_enlarge_lower) + { + if (priv->pshare->txop_enlarge) { + priv->pshare->txop_enlarge = 0; + if (priv->pshare->iot_mode_enable) + switch_turbo++; + } + } + +#if((DM_ODM_SUPPORT_TYPE==ODM_AP)&&( defined LOW_TP_TXOP)) + // for Intel IOT, need to enlarge CW MAX from 6 to 10 + if (pstat && pstat->IOTPeer==HT_IOT_PEER_INTEL && (((pstat->tx_avarage+pstat->rx_avarage)>>10) < + priv->pshare->rf_ft_var.cwmax_enhance_thd)) + { + if (!priv->pshare->BE_cwmax_enhance && priv->pshare->iot_mode_enable) + { + priv->pshare->BE_cwmax_enhance = 1; + switch_turbo++; + } + } else { + if (priv->pshare->BE_cwmax_enhance) { + priv->pshare->BE_cwmax_enhance = 0; + switch_turbo++; + } + } +#endif + } +#endif + priv->pshare->current_tx_bytes = 0; + priv->pshare->current_rx_bytes = 0; + }else { + if ((GET_CHIP_VER(priv) == VERSION_8881A)||(GET_CHIP_VER(priv) == VERSION_8192E)|| (GET_CHIP_VER(priv) == VERSION_8188E) ){ + unsigned int uldl_tp = (priv->pshare->current_tx_bytes+priv->pshare->current_rx_bytes)>>17; + if((uldl_tp > 40) && (priv->pshare->agg_to!= 1)) { + RTL_W8(0x462, 0x08); + priv->pshare->agg_to = 1; + } else if((uldl_tp < 35) && (priv->pshare->agg_to !=0)) { + RTL_W8(0x462, 0x02); + priv->pshare->agg_to = 0; + } + } + } + +#if((DM_ODM_SUPPORT_TYPE==ODM_AP)&& defined( SW_TX_QUEUE)) + if(AMPDU_ENABLE) { +#ifdef TX_EARLY_MODE + if (GET_TX_EARLY_MODE) { + if (!GET_EM_SWQ_ENABLE && + ((priv->assoc_num > 1) || + (pstat && pstat->IOTPeer != HT_IOT_PEER_UNKNOWN))) { + if ((priv->pshare->em_tx_byte_cnt >> 17) > EM_TP_UP_BOUND) + priv->pshare->reach_tx_limit_cnt++; + else + priv->pshare->reach_tx_limit_cnt = 0; + + if (priv->pshare->txop_enlarge && priv->pshare->reach_tx_limit_cnt) { //>= WAIT_TP_TIME// + GET_EM_SWQ_ENABLE = 1; + priv->pshare->reach_tx_limit_cnt = 0; + + if (pstat->IOTPeer == HT_IOT_PEER_INTEL) + MAX_EM_QUE_NUM = 12; + else if (pstat->IOTPeer == HT_IOT_PEER_RALINK) + MAX_EM_QUE_NUM = 10; + + enable_em(priv); + } + } + else if (GET_EM_SWQ_ENABLE) { + if ((priv->pshare->em_tx_byte_cnt >> 17) < EM_TP_LOW_BOUND) + priv->pshare->reach_tx_limit_cnt++; + else + priv->pshare->reach_tx_limit_cnt = 0; + + if (!priv->pshare->txop_enlarge || priv->pshare->reach_tx_limit_cnt >= WAIT_TP_TIME) { + GET_EM_SWQ_ENABLE = 0; + priv->pshare->reach_tx_limit_cnt = 0; + disable_em(priv); + } + } + } +#endif + +#if defined(CONFIG_WLAN_HAL_8881A) || defined(CONFIG_WLAN_HAL_8192EE) || defined(CONFIG_RTL_8812_SUPPORT) || defined(CONFIG_WLAN_HAL_8814AE) + if (pDM_Odm->SupportICType == ODM_RTL8881A || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8814A) { + if (priv->assoc_num > 9) + { + if (priv->swq_txmac_chg >= priv->pshare->rf_ft_var.swq_en_highthd){ + if ((priv->swq_decision == 0)){ + switch_turbo++; + if (priv->pshare->txop_enlarge == 0) + priv->pshare->txop_enlarge = 2; + priv->swq_decision = 1; + } + else + { + if ((switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0)) + { + priv->pshare->txop_enlarge = 2; + switch_turbo--; + } + } + } + else if(priv->swq_txmac_chg <= priv->pshare->rf_ft_var.swq_dis_lowthd){ + priv->swq_decision = 0; + } + else if ((priv->swq_decision == 1) && (switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0)) { + priv->pshare->txop_enlarge = 2; + switch_turbo--; + } + } else { + priv->swq_decision = 0; + } + } else if(CONFIG_WLAN_NOT_HAL_EXIST) +#endif + { + if (priv->assoc_num > 1) + { + if (priv->swq_txmac_chg >= priv->pshare->rf_ft_var.swq_en_highthd){ + if ((priv->swq_decision == 0)){ + switch_turbo++; + if (priv->pshare->txop_enlarge == 0) + priv->pshare->txop_enlarge = 2; + priv->swq_decision = 1; + } + else + { + if ((switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0)) + { + priv->pshare->txop_enlarge = 2; + switch_turbo--; + } + } + } + else if(priv->swq_txmac_chg <= priv->pshare->rf_ft_var.swq_dis_lowthd){ + priv->swq_decision = 0; + } + else if ((priv->swq_decision == 1) && (switch_turbo > 0) && (priv->pshare->txop_enlarge == 0) && (priv->pshare->iot_mode_enable != 0)) { + priv->pshare->txop_enlarge = 2; + switch_turbo--; + } + } + //#if (defined CONFIG_RTL_819XD)) + else if (priv->assoc_num == 1 && (priv->up_time % 2 == 0) +#if (DM_ODM_SUPPORT_TYPE==ODM_AP) && defined(TX_EARLY_MODE) + && (!GET_TX_EARLY_MODE || !GET_EM_SWQ_ENABLE) +#endif + ) { + if ((pstat) && (pstat->ADDBA_ready[0] | pstat->ADDBA_ready[3])) { + //int en_thd = 14417920>>(priv->up_time % 2); + avg_tp = (pstat->current_tx_bytes >> 17); + + //if ((priv->swq_decision == 0) && (pstat->current_tx_bytes > en_thd) && (pstat->current_rx_bytes > en_thd) ) { //50Mbps + if ((priv->swq_decision == 0) && (avg_tp > TP_HIGH_WATER_MARK)) { //55Mbps + //printk("[%s:%d] swq_decision=1 current_tp: %d Mbps\n", __FUNCTION__, __LINE__, avg_tp); + priv->swq_decision = 1; + } + //else if ((priv->swq_decision == 1) && ((pstat->tx_avarage < 4587520) || (pstat->rx_avarage < 4587520))) { //35Mbps + else if ((priv->swq_decision == 1) && (avg_tp < TP_LOW_WATER_MARK)) { //35Mbps + //printk("[%s:%d] swq_decision=0 current_tp: %d Mbps\n", __FUNCTION__, __LINE__, avg_tp); + priv->swq_decision = 0; + } + } else { + priv->swq_decision = 0; + } + } + } + if( (priv->swq_decision == 1) +#if (DM_ODM_SUPPORT_TYPE==ODM_AP) && defined(TX_EARLY_MODE) + || (GET_EM_SWQ_ENABLE == 1) +#endif + ) { + priv->swq_en = 1; + priv->swqen_keeptime = priv->up_time; + } else { + priv->swq_en = 0; + priv->swqen_keeptime = 0; + } + } +#endif + +#ifdef WIFI_WMM +#ifdef LOW_TP_TXOP + if ((!priv->pmib->dot11OperationEntry.wifi_specific || (priv->pmib->dot11OperationEntry.wifi_specific == 2)) + && QOS_ENABLE) { + if (switch_turbo || priv->pshare->rf_ft_var.low_tp_txop) { + unsigned int thd_tp; + unsigned char under_thd; + unsigned int curr_tp; + + if (priv->pmib->dot11BssType.net_work_type & (ODM_WM_N24G|ODM_WM_N5G| ODM_WM_G)) + { + // Determine the upper bound throughput threshold. + if (priv->pmib->dot11BssType.net_work_type & (ODM_WM_N24G|ODM_WM_N5G)) { + if (priv->assoc_num && priv->assoc_num != priv->pshare->ht_sta_num) + thd_tp = priv->pshare->rf_ft_var.low_tp_txop_thd_g; + else + thd_tp = priv->pshare->rf_ft_var.low_tp_txop_thd_n; + } + else + thd_tp = priv->pshare->rf_ft_var.low_tp_txop_thd_g; + + // Determine to close txop. +#if defined(UNIVERSAL_REPEATER) || defined(MBSSID) + if(IS_STA_VALID(pstat)) + { + struct rtl8192cd_priv *tmppriv; + struct aid_obj *aidarray; + aidarray = container_of(pstat, struct aid_obj, station); + tmppriv = aidarray->priv; + + curr_tp = (unsigned int)(tmppriv->ext_stats.tx_avarage>>17) + (unsigned int)(tmppriv->ext_stats.rx_avarage>>17); + } + else +#endif + curr_tp = (unsigned int)(priv->ext_stats.tx_avarage>>17) + (unsigned int)(priv->ext_stats.rx_avarage>>17); + if (curr_tp <= thd_tp && curr_tp >= priv->pshare->rf_ft_var.low_tp_txop_thd_low) + under_thd = 1; + else + under_thd = 0; + } + else + { + under_thd = 0; + } + + if (switch_turbo) + { + priv->pshare->rf_ft_var.low_tp_txop_close = under_thd; + priv->pshare->rf_ft_var.low_tp_txop_count = 0; + } + else if (priv->pshare->iot_mode_enable && (priv->pshare->rf_ft_var.low_tp_txop_close != under_thd)) { + priv->pshare->rf_ft_var.low_tp_txop_count++; + if (priv->pshare->rf_ft_var.low_tp_txop_close) { + priv->pshare->rf_ft_var.low_tp_txop_count = priv->pshare->rf_ft_var.low_tp_txop_delay; + } + if (priv->pshare->rf_ft_var.low_tp_txop_count ==priv->pshare->rf_ft_var.low_tp_txop_delay) + + { + priv->pshare->rf_ft_var.low_tp_txop_count = 0; + priv->pshare->rf_ft_var.low_tp_txop_close = under_thd; + switch_turbo++; + } + } + else + { + priv->pshare->rf_ft_var.low_tp_txop_count = 0; + } + } + } +#endif + +#ifdef WMM_DSCP_C42 + if (switch_turbo) { + if (!priv->pshare->iot_mode_enable && !priv->pshare->aggrmax_change) { + RTL_W16(0x4ca, 0x0404); + priv->pshare->aggrmax_change = 1; + } + else if (priv->pshare->iot_mode_enable && priv->pshare->aggrmax_change) { + RTL_W16(0x4ca, priv->pshare->aggrmax_bak); + priv->pshare->aggrmax_change = 0; + } + } +#endif +#ifdef TX_EARLY_MODE + unsigned int em_tp = ((priv->ext_stats.tx_avarage>>17) + (priv->ext_stats.rx_avarage>>17)); + if (em_tp > 80) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (0x5e << 16) | (4 << 12) | (3 << 8) | 0x19); + else //if (em_tp < 75) + ODM_Write4Byte(pDM_Odm, ODM_EDCA_BE_PARAM, (0x5e << 16) | (6 << 12) | (5 << 8) | 0x2b); +#endif + if (switch_turbo) + ODM_IotEdcaSwitch( pDM_Odm, priv->pshare->iot_mode_enable ); +#endif +} +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_EdcaTurboCheck.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_EdcaTurboCheck.h new file mode 100755 index 000000000000..4557d158ce99 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_EdcaTurboCheck.h @@ -0,0 +1,152 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMEDCATURBOCHECK_H__ +#define __PHYDMEDCATURBOCHECK_H__ + +#define EDCATURBO_VERSION "1.0" + +typedef struct _EDCA_TURBO_ +{ + BOOLEAN bCurrentTurboEDCA; + BOOLEAN bIsCurRDLState; + + #if(DM_ODM_SUPPORT_TYPE == ODM_CE ) + u4Byte prv_traffic_idx; // edca turbo + #endif + +}EDCA_T,*pEDCA_T; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +static u4Byte edca_setting_UL[HT_IOT_PEER_MAX] = +// UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU MARVELL 92U_AP SELF_AP(DownLink/Tx) +{ 0x5e4322, 0xa44f, 0x5e4322, 0x5ea32b, 0x5ea422, 0x5ea322, 0x3ea430, 0x5ea42b, 0x5ea44f, 0x5e4322, 0x5e4322}; + + +static u4Byte edca_setting_DL[HT_IOT_PEER_MAX] = +// UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU, MARVELL 92U_AP SELF_AP(UpLink/Rx) +{ 0xa44f, 0x5ea44f, 0x5e4322, 0x5ea42b, 0xa44f, 0xa630, 0x5ea630, 0x5ea42b, 0xa44f, 0xa42b, 0xa42b}; + +static u4Byte edca_setting_DL_GMode[HT_IOT_PEER_MAX] = +// UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU, MARVELL 92U_AP SELF_AP +{ 0x4322, 0xa44f, 0x5e4322, 0xa42b, 0x5e4322, 0x4322, 0xa42b, 0x5ea42b, 0xa44f, 0x5e4322, 0x5ea42b}; + + +//============================================================ +// EDCA Paramter for AP/ADSL by Mingzhi 2011-11-22 +//============================================================ +#elif (DM_ODM_SUPPORT_TYPE &ODM_ADSL) +enum qos_prio { BK, BE, VI, VO, VI_AG, VO_AG }; + +static const struct ParaRecord rtl_ap_EDCA[] = +{ +//ACM,AIFSN, ECWmin, ECWmax, TXOplimit + {0, 7, 4, 10, 0}, //BK + {0, 3, 4, 6, 0}, //BE + {0, 1, 3, 4, 188}, //VI + {0, 1, 2, 3, 102}, //VO + {0, 1, 3, 4, 94}, //VI_AG + {0, 1, 2, 3, 47}, //VO_AG +}; + +static const struct ParaRecord rtl_sta_EDCA[] = +{ +//ACM,AIFSN, ECWmin, ECWmax, TXOplimit + {0, 7, 4, 10, 0}, + {0, 3, 4, 10, 0}, + {0, 2, 3, 4, 188}, + {0, 2, 2, 3, 102}, + {0, 2, 3, 4, 94}, + {0, 2, 2, 3, 47}, +}; +#endif + + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#ifdef WIFI_WMM +VOID +ODM_IotEdcaSwitch( + IN PVOID pDM_VOID, + IN unsigned char enable + ); +#endif + +BOOLEAN +ODM_ChooseIotMainSTA( + IN PVOID pDM_VOID, + IN PSTA_INFO_T pstat + ); +#endif + +VOID +odm_EdcaTurboCheck( + IN PVOID pDM_VOID + ); +VOID +ODM_EdcaTurboInit( + IN PVOID pDM_VOID +); + +#if(DM_ODM_SUPPORT_TYPE==ODM_WIN) +VOID +odm_EdcaTurboCheckMP( + IN PVOID pDM_VOID + ); + +//check if edca turbo is disabled +BOOLEAN +odm_IsEdcaTurboDisable( + IN PVOID pDM_VOID +); +//choose edca paramter for special IOT case +VOID +ODM_EdcaParaSelByIot( + IN PVOID pDM_VOID, + OUT u4Byte *EDCA_BE_UL, + OUT u4Byte *EDCA_BE_DL + ); +//check if it is UL or DL +VOID +odm_EdcaChooseTrafficIdx( + IN PVOID pDM_VOID, + IN u8Byte cur_tx_bytes, + IN u8Byte cur_rx_bytes, + IN BOOLEAN bBiasOnRx, + OUT BOOLEAN *pbIsCurRDLState + ); + +#elif (DM_ODM_SUPPORT_TYPE==ODM_CE) +VOID +odm_EdcaTurboCheckCE( + IN PVOID pDM_VOID + ); +#else +VOID +odm_IotEngine( + IN PVOID pDM_VOID + ); + +VOID +odm_EdcaParaInit( + IN PVOID pDM_VOID + ); +#endif + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_HWConfig.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_HWConfig.c new file mode 100755 index 000000000000..e8dc0a60b356 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_HWConfig.c @@ -0,0 +1,2362 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ + +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +#define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig_MP_##ic##txt(pDM_Odm)) +#define READ_AND_CONFIG_TC(ic, txt) (ODM_ReadAndConfig_TC_##ic##txt(pDM_Odm)) + + +#if (TESTCHIP_SUPPORT == 1) +#define READ_AND_CONFIG(ic, txt) do {\ + if (pDM_Odm->bIsMPChip)\ + READ_AND_CONFIG_MP(ic,txt);\ + else\ + READ_AND_CONFIG_TC(ic,txt);\ + } while(0) +#else + #define READ_AND_CONFIG READ_AND_CONFIG_MP +#endif + + +#define READ_FIRMWARE_MP(ic, txt) (ODM_ReadFirmware_MP_##ic##txt(pDM_Odm, pFirmware, pSize)) +#define READ_FIRMWARE_TC(ic, txt) (ODM_ReadFirmware_TC_##ic##txt(pDM_Odm, pFirmware, pSize)) + +#if (TESTCHIP_SUPPORT == 1) +#define READ_FIRMWARE(ic, txt) do {\ + if (pDM_Odm->bIsMPChip)\ + READ_FIRMWARE_MP(ic,txt);\ + else\ + READ_FIRMWARE_TC(ic,txt);\ + } while(0) +#else +#define READ_FIRMWARE READ_FIRMWARE_MP +#endif + +#define GET_VERSION_MP(ic, txt) (ODM_GetVersion_MP_##ic##txt()) +#define GET_VERSION_TC(ic, txt) (ODM_GetVersion_TC_##ic##txt()) +#define GET_VERSION(ic, txt) (pDM_Odm->bIsMPChip?GET_VERSION_MP(ic,txt):GET_VERSION_TC(ic,txt)) + + +u1Byte +odm_QueryRxPwrPercentage( + IN s1Byte AntPower + ) +{ + if ((AntPower <= -100) || (AntPower >= 20)) + { + return 0; + } + else if (AntPower >= 0) + { + return 100; + } + else + { + return (100+AntPower); + } + +} + +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +// +// 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer. +// IF other SW team do not support the feature, remove this section.?? +// +s4Byte +odm_SignalScaleMapping_92CSeries_patch_RT_CID_819x_Lenovo( + IN OUT PDM_ODM_T pDM_Odm, + s4Byte CurrSig +) +{ + s4Byte RetSig = 0; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + //if(pDM_Odm->SupportInterface == ODM_ITRF_PCIE) + { + // Step 1. Scale mapping. + // 20100611 Joseph: Re-tunning RSSI presentation for Lenovo. + // 20100426 Joseph: Modify Signal strength mapping. + // This modification makes the RSSI indication similar to Intel solution. + // 20100414 Joseph: Tunning RSSI for Lenovo according to RTL8191SE. + if(CurrSig >= 54 && CurrSig <= 100) + { + RetSig = 100; + } + else if(CurrSig>=42 && CurrSig <= 53 ) + { + RetSig = 95; + } + else if(CurrSig>=36 && CurrSig <= 41 ) + { + RetSig = 74 + ((CurrSig - 36) *20)/6; + } + else if(CurrSig>=33 && CurrSig <= 35 ) + { + RetSig = 65 + ((CurrSig - 33) *8)/2; + } + else if(CurrSig>=18 && CurrSig <= 32 ) + { + RetSig = 62 + ((CurrSig - 18) *2)/15; + } + else if(CurrSig>=15 && CurrSig <= 17 ) + { + RetSig = 33 + ((CurrSig - 15) *28)/2; + } + else if(CurrSig>=10 && CurrSig <= 14 ) + { + RetSig = 39; + } + else if(CurrSig>=8 && CurrSig <= 9 ) + { + RetSig = 33; + } + else if(CurrSig <= 8 ) + { + RetSig = 19; + } + } +#endif //ENDIF (DM_ODM_SUPPORT_TYPE == ODM_WIN) + return RetSig; +} + +s4Byte +odm_SignalScaleMapping_92CSeries_patch_RT_CID_819x_Netcore( + IN OUT PDM_ODM_T pDM_Odm, + s4Byte CurrSig +) +{ + s4Byte RetSig = 0; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + //if(pDM_Odm->SupportInterface == ODM_ITRF_USB) + { + // Netcore request this modification because 2009.04.13 SU driver use it. + if(CurrSig >= 31 && CurrSig <= 100) + { + RetSig = 100; + } + else if(CurrSig >= 21 && CurrSig <= 30) + { + RetSig = 90 + ((CurrSig - 20) / 1); + } + else if(CurrSig >= 11 && CurrSig <= 20) + { + RetSig = 80 + ((CurrSig - 10) / 1); + } + else if(CurrSig >= 7 && CurrSig <= 10) + { + RetSig = 69 + (CurrSig - 7); + } + else if(CurrSig == 6) + { + RetSig = 54; + } + else if(CurrSig == 5) + { + RetSig = 45; + } + else if(CurrSig == 4) + { + RetSig = 36; + } + else if(CurrSig == 3) + { + RetSig = 27; + } + else if(CurrSig == 2) + { + RetSig = 18; + } + else if(CurrSig == 1) + { + RetSig = 9; + } + else + { + RetSig = CurrSig; + } + } +#endif //ENDIF (DM_ODM_SUPPORT_TYPE == ODM_WIN) + return RetSig; +} + + +s4Byte +odm_SignalScaleMapping_92CSeries( + IN OUT PDM_ODM_T pDM_Odm, + IN s4Byte CurrSig +) +{ + s4Byte RetSig = 0; +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) + if(pDM_Odm->SupportInterface == ODM_ITRF_PCIE) + { + // Step 1. Scale mapping. + if(CurrSig >= 61 && CurrSig <= 100) + { + RetSig = 90 + ((CurrSig - 60) / 4); + } + else if(CurrSig >= 41 && CurrSig <= 60) + { + RetSig = 78 + ((CurrSig - 40) / 2); + } + else if(CurrSig >= 31 && CurrSig <= 40) + { + RetSig = 66 + (CurrSig - 30); + } + else if(CurrSig >= 21 && CurrSig <= 30) + { + RetSig = 54 + (CurrSig - 20); + } + else if(CurrSig >= 5 && CurrSig <= 20) + { + RetSig = 42 + (((CurrSig - 5) * 2) / 3); + } + else if(CurrSig == 4) + { + RetSig = 36; + } + else if(CurrSig == 3) + { + RetSig = 27; + } + else if(CurrSig == 2) + { + RetSig = 18; + } + else if(CurrSig == 1) + { + RetSig = 9; + } + else + { + RetSig = CurrSig; + } + } +#endif + +#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) ||(DEV_BUS_TYPE == RT_SDIO_INTERFACE)) + if((pDM_Odm->SupportInterface == ODM_ITRF_USB) || (pDM_Odm->SupportInterface == ODM_ITRF_SDIO)) + { + if(CurrSig >= 51 && CurrSig <= 100) + { + RetSig = 100; + } + else if(CurrSig >= 41 && CurrSig <= 50) + { + RetSig = 80 + ((CurrSig - 40)*2); + } + else if(CurrSig >= 31 && CurrSig <= 40) + { + RetSig = 66 + (CurrSig - 30); + } + else if(CurrSig >= 21 && CurrSig <= 30) + { + RetSig = 54 + (CurrSig - 20); + } + else if(CurrSig >= 10 && CurrSig <= 20) + { + RetSig = 42 + (((CurrSig - 10) * 2) / 3); + } + else if(CurrSig >= 5 && CurrSig <= 9) + { + RetSig = 22 + (((CurrSig - 5) * 3) / 2); + } + else if(CurrSig >= 1 && CurrSig <= 4) + { + RetSig = 6 + (((CurrSig - 1) * 3) / 2); + } + else + { + RetSig = CurrSig; + } + } + +#endif + return RetSig; +} +s4Byte +odm_SignalScaleMapping( + IN OUT PDM_ODM_T pDM_Odm, + IN s4Byte CurrSig +) +{ + if( (pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->SupportInterface != ODM_ITRF_PCIE) && //USB & SDIO + (pDM_Odm->PatchID==10))//pMgntInfo->CustomerID == RT_CID_819x_Netcore + { + return odm_SignalScaleMapping_92CSeries_patch_RT_CID_819x_Netcore(pDM_Odm,CurrSig); + } + else if( (pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->SupportInterface == ODM_ITRF_PCIE) && + (pDM_Odm->PatchID==19))//pMgntInfo->CustomerID == RT_CID_819x_Lenovo) + { + return odm_SignalScaleMapping_92CSeries_patch_RT_CID_819x_Lenovo(pDM_Odm, CurrSig); + } + else{ + return odm_SignalScaleMapping_92CSeries(pDM_Odm,CurrSig); + } + +} +#endif + + +static u1Byte odm_SQ_process_patch_RT_CID_819x_Lenovo( + IN PDM_ODM_T pDM_Odm, + IN u1Byte isCCKrate, + IN u1Byte PWDB_ALL, + IN u1Byte path, + IN u1Byte RSSI +) +{ + u1Byte SQ = 0; +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + + if(isCCKrate){ + + if(IS_HARDWARE_TYPE_8723AE(pDM_Odm->Adapter)) + { + + // + // Expected signal strength and bars indication at Lenovo lab. 2013.04.11 + // 802.11n, 802.11b, 802.11g only at channel 6 + // + // Attenuation (dB) OS Signal Bars RSSI by Xirrus (dBm) + // 50 5 -52 + // 55 5 -54 + // 60 5 -55 + // 65 5 -59 + // 70 5 -63 + // 75 5 -66 + // 80 4 -72 + // 85 3 -75 + // 90 3 -80 + // 95 2 -85 + // 100 1 -89 + // 102 1 -90 + // 104 1 -91 + // + RT_TRACE(COMP_DBG, DBG_WARNING, ("odm_SQ_process_patch_RT_CID_819x_Lenovo\n")); + +#if OS_WIN_FROM_WIN8(OS_VERSION) + if(PWDB_ALL >= 50) + SQ = 100; + else if(PWDB_ALL >= 23 && PWDB_ALL < 50) + SQ = 80; + else if(PWDB_ALL >= 18 && PWDB_ALL < 23) + SQ = 60; + else if(PWDB_ALL >= 8 && PWDB_ALL < 18) + SQ = 40; + else + SQ = 10; +#else + if(PWDB_ALL >= 34) + SQ = 100; + else if(PWDB_ALL >= 23 && PWDB_ALL < 34) + SQ = 80; + else if(PWDB_ALL >= 18 && PWDB_ALL < 23) + SQ = 60; + else if(PWDB_ALL >= 8 && PWDB_ALL < 18) + SQ = 40; + else + SQ = 10; + + if(PWDB_ALL == 0)// Abnormal case, do not indicate the value above 20 on Win7 + SQ = 20; +#endif + + } + else if(IS_HARDWARE_TYPE_8192E(pDM_Odm->Adapter)){ + + // + // Expected signal strength and bars indication at Lenovo lab. 2013.04.11 + // 802.11n, 802.11b, 802.11g only at channel 6 + // + // Attenuation (dB) OS Signal Bars RSSI by Xirrus (dBm) + // 50 5 -49 + // 55 5 -49 + // 60 5 -50 + // 65 5 -51 + // 70 5 -52 + // 75 5 -54 + // 80 5 -55 + // 85 4 -60 + // 90 3 -63 + // 95 3 -65 + // 100 2 -67 + // 102 2 -67 + // 104 1 -70 + // + + if(PWDB_ALL >= 50) + SQ = 100; + else if(PWDB_ALL >= 35 && PWDB_ALL < 50) + SQ = 80; + else if(PWDB_ALL >= 31 && PWDB_ALL < 35) + SQ = 60; + else if(PWDB_ALL >= 22 && PWDB_ALL < 31) + SQ = 40; + else if(PWDB_ALL >= 18 && PWDB_ALL < 22) + SQ = 20; + else + SQ = 10; + } + else + { + if(PWDB_ALL >= 50) + SQ = 100; + else if(PWDB_ALL >= 35 && PWDB_ALL < 50) + SQ = 80; + else if(PWDB_ALL >= 22 && PWDB_ALL < 35) + SQ = 60; + else if(PWDB_ALL >= 18 && PWDB_ALL < 22) + SQ = 40; + else + SQ = 10; + } + + } + else + {//OFDM rate + + if(IS_HARDWARE_TYPE_8723AE(pDM_Odm->Adapter) || + IS_HARDWARE_TYPE_8192E(pDM_Odm->Adapter)) + { + if(RSSI >= 45) + SQ = 100; + else if(RSSI >= 22 && RSSI < 45) + SQ = 80; + else if(RSSI >= 18 && RSSI < 22) + SQ = 40; + else + SQ = 20; + } + else + { + if(RSSI >= 45) + SQ = 100; + else if(RSSI >= 22 && RSSI < 45) + SQ = 80; + else if(RSSI >= 18 && RSSI < 22) + SQ = 40; + else + SQ = 20; + } + } + + RT_TRACE(COMP_DBG, DBG_TRACE, ("isCCKrate(%#d), PWDB_ALL(%#d), RSSI(%#d), SQ(%#d)\n", isCCKrate, PWDB_ALL, RSSI, SQ)); + +#endif + return SQ; +} + +static u1Byte odm_SQ_process_patch_RT_CID_819x_Acer( + IN PDM_ODM_T pDM_Odm, + IN u1Byte isCCKrate, + IN u1Byte PWDB_ALL, + IN u1Byte path, + IN u1Byte RSSI +) +{ + u1Byte SQ = 0; + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + + if(isCCKrate){ + + RT_TRACE(COMP_DBG, DBG_WARNING, ("odm_SQ_process_patch_RT_Acer\n")); + +#if OS_WIN_FROM_WIN8(OS_VERSION) + + if(PWDB_ALL >= 50) + SQ = 100; + else if(PWDB_ALL >= 35 && PWDB_ALL < 50) + SQ = 80; + else if(PWDB_ALL >= 30 && PWDB_ALL < 35) + SQ = 60; + else if(PWDB_ALL >= 25 && PWDB_ALL < 30) + SQ = 40; + else if(PWDB_ALL >= 20 && PWDB_ALL < 25) + SQ = 20; + else + SQ = 10; +#else + if(PWDB_ALL >= 50) + SQ = 100; + else if(PWDB_ALL >= 35 && PWDB_ALL < 50) + SQ = 80; + else if(PWDB_ALL >= 30 && PWDB_ALL < 35) + SQ = 60; + else if(PWDB_ALL >= 25 && PWDB_ALL < 30) + SQ = 40; + else if(PWDB_ALL >= 20 && PWDB_ALL < 25) + SQ = 20; + else + SQ = 10; + + if(PWDB_ALL == 0)// Abnormal case, do not indicate the value above 20 on Win7 + SQ = 20; +#endif + + + + } + else + {//OFDM rate + + if(IS_HARDWARE_TYPE_8723AE(pDM_Odm->Adapter) || + IS_HARDWARE_TYPE_8192E(pDM_Odm->Adapter)) + { + if(RSSI >= 45) + SQ = 100; + else if(RSSI >= 22 && RSSI < 45) + SQ = 80; + else if(RSSI >= 18 && RSSI < 22) + SQ = 40; + else + SQ = 20; + } + else + { + if(RSSI >= 35) + SQ = 100; + else if(RSSI >= 30 && RSSI < 35) + SQ = 80; + else if(RSSI >= 25 && RSSI < 30) + SQ = 40; + else + SQ = 20; + } + } + + RT_TRACE(COMP_DBG, DBG_LOUD, ("isCCKrate(%#d), PWDB_ALL(%#d), RSSI(%#d), SQ(%#d)\n", isCCKrate, PWDB_ALL, RSSI, SQ)); + +#endif + return SQ; +} + +static u1Byte +odm_EVMdbToPercentage( + IN s1Byte Value + ) +{ + // + // -33dB~0dB to 0%~99% + // + s1Byte ret_val; + + ret_val = Value; + ret_val /= 2; + + //DbgPrint("Value=%d\n", Value); + //ODM_RT_DISP(FRX, RX_PHY_SQ, ("EVMdbToPercentage92C Value=%d / %x \n", ret_val, ret_val)); + + if(ret_val >= 0) + ret_val = 0; + if(ret_val <= -33) + ret_val = -33; + + ret_val = 0 - ret_val; + ret_val*=3; + + if(ret_val == 99) + ret_val = 100; + + return(ret_val); +} + +static u1Byte +odm_EVMdbm_JaguarSeries( + IN s1Byte Value + ) +{ + s1Byte ret_val = Value; + + // -33dB~0dB to 33dB ~ 0dB + if(ret_val == -128) + ret_val = 127; + else if (ret_val < 0) + ret_val = 0 - ret_val; + + ret_val = ret_val >> 1; + return ret_val; +} + +static u2Byte +odm_Cfo( + IN s1Byte Value +) +{ + s2Byte ret_val; + + if (Value < 0) + { + ret_val = 0 - Value; + ret_val = (ret_val << 1) + (ret_val >> 1) ; // *2.5~=312.5/2^7 + ret_val = ret_val | BIT12; // set bit12 as 1 for negative cfo + } + else + { + ret_val = Value; + ret_val = (ret_val << 1) + (ret_val>>1) ; // *2.5~=312.5/2^7 + } + return ret_val; +} + +#if(ODM_IC_11N_SERIES_SUPPORT == 1) +VOID +odm_RxPhyStatus92CSeries_Parsing( + IN OUT PDM_ODM_T pDM_Odm, + OUT PODM_PHY_INFO_T pPhyInfo, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ + SWAT_T *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + u1Byte i, Max_spatial_stream; + s1Byte rx_pwr[4], rx_pwr_all=0; + u1Byte EVM, PWDB_ALL = 0, PWDB_ALL_BT; + u1Byte RSSI, total_rssi=0; + BOOLEAN isCCKrate=FALSE; + u1Byte rf_rx_num = 0; + u1Byte cck_highpwr = 0; + u1Byte LNA_idx, VGA_idx; + PPHY_STATUS_RPT_8192CD_T pPhyStaRpt = (PPHY_STATUS_RPT_8192CD_T)pPhyStatus; + + isCCKrate = (pPktinfo->DataRate <= DESC_RATE11M)?TRUE :FALSE; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_A] = -1; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_B] = -1; + + + if(isCCKrate) + { + u1Byte report; + u1Byte cck_agc_rpt; + + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK++; + // + // (1)Hardware does not provide RSSI for CCK + // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) + // + + //if(pHalData->eRFPowerState == eRfOn) + cck_highpwr = pDM_Odm->bCckHighPower; + //else + // cck_highpwr = FALSE; + + cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a ; + + //2011.11.28 LukeLee: 88E use different LNA & VGA gain table + //The RSSI formula should be modified according to the gain table + //In 88E, cck_highpwr is always set to 1 + if(pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B)) + { + LNA_idx = ((cck_agc_rpt & 0xE0) >>5); + VGA_idx = (cck_agc_rpt & 0x1F); + if(pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8192E)) + { + switch(LNA_idx) + { + case 7: + if(VGA_idx <= 27) + rx_pwr_all = -100 + 2*(27-VGA_idx); //VGA_idx = 27~2 + else + rx_pwr_all = -100; + break; + case 6: + rx_pwr_all = -48 + 2*(2-VGA_idx); //VGA_idx = 2~0 + break; + case 5: + rx_pwr_all = -42 + 2*(7-VGA_idx); //VGA_idx = 7~5 + break; + case 4: + rx_pwr_all = -36 + 2*(7-VGA_idx); //VGA_idx = 7~4 + break; + case 3: + //rx_pwr_all = -28 + 2*(7-VGA_idx); //VGA_idx = 7~0 + rx_pwr_all = -24 + 2*(7-VGA_idx); //VGA_idx = 7~0 + break; + case 2: + if(cck_highpwr) + rx_pwr_all = -12 + 2*(5-VGA_idx); //VGA_idx = 5~0 + else + rx_pwr_all = -6+ 2*(5-VGA_idx); + break; + case 1: + rx_pwr_all = 8-2*VGA_idx; + break; + case 0: + rx_pwr_all = 14-2*VGA_idx; + break; + default: + //DbgPrint("CCK Exception default\n"); + break; + } + rx_pwr_all += 6; + + //2012.10.08 LukeLee: Modify for 92E CCK RSSI + if(pDM_Odm->SupportICType == ODM_RTL8192E) + rx_pwr_all += 10; + + PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + if(cck_highpwr == FALSE) + { + if(PWDB_ALL >= 80) + PWDB_ALL = ((PWDB_ALL-80)<<1)+((PWDB_ALL-80)>>1)+80; + else if((PWDB_ALL <= 78) && (PWDB_ALL >= 20)) + PWDB_ALL += 3; + if(PWDB_ALL>100) + PWDB_ALL = 100; + } + } + else if(pDM_Odm->SupportICType & (ODM_RTL8723B)) + { +#if (RTL8723B_SUPPORT == 1) + rx_pwr_all = odm_CCKRSSI_8723B(LNA_idx,VGA_idx); + PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + if(PWDB_ALL>100) + PWDB_ALL = 100; +#endif + } + } + else + { + if(!cck_highpwr) + { + report =( cck_agc_rpt & 0xc0 )>>6; + switch(report) + { + // 03312009 modified by cosa + // Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion + // Note: different RF with the different RNA gain. + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } + else + { + //report = pDrvInfo->cfosho[0] & 0x60; + //report = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a& 0x60; + + report = (cck_agc_rpt & 0x60)>>5; + switch(report) + { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1) ; + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f)<<1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1) ; + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1) ; + break; + } + } + + PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + + //Modification for ext-LNA board + if(pDM_Odm->BoardType & (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_PA)) + { + if((cck_agc_rpt>>7) == 0){ + PWDB_ALL = (PWDB_ALL>94)?100:(PWDB_ALL +6); + } + else + { + if(PWDB_ALL > 38) + PWDB_ALL -= 16; + else + PWDB_ALL = (PWDB_ALL<=16)?(PWDB_ALL>>2):(PWDB_ALL -12); + } + + //CCK modification + if(PWDB_ALL > 25 && PWDB_ALL <= 60) + PWDB_ALL += 6; + //else if (PWDB_ALL <= 25) + // PWDB_ALL += 8; + } + else//Modification for int-LNA board + { + if(PWDB_ALL > 99) + PWDB_ALL -= 8; + else if(PWDB_ALL > 50 && PWDB_ALL <= 68) + PWDB_ALL += 4; + } + } + + pPhyInfo->RxPWDBAll = PWDB_ALL; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->BTRxRSSIPercentage = PWDB_ALL; + pPhyInfo->RecvSignalPower = rx_pwr_all; +#endif + // + // (3) Get Signal Quality (EVM) + // + //if(pPktinfo->bPacketMatchBSSID) + { + u1Byte SQ,SQ_rpt; + + if((pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->PatchID==RT_CID_819x_Lenovo)){ + SQ = odm_SQ_process_patch_RT_CID_819x_Lenovo(pDM_Odm,isCCKrate,PWDB_ALL,0,0); + } + else if((pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->PatchID==RT_CID_819x_Acer)) + { + SQ = odm_SQ_process_patch_RT_CID_819x_Acer(pDM_Odm,isCCKrate,PWDB_ALL,0,0); + } + else if(pPhyInfo->RxPWDBAll > 40 && !pDM_Odm->bInHctTest){ + SQ = 100; + } + else{ + SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all; + + if(SQ_rpt > 64) + SQ = 0; + else if (SQ_rpt < 20) + SQ = 100; + else + SQ = ((64-SQ_rpt) * 100) / 44; + + } + + //DbgPrint("cck SQ = %d\n", SQ); + pPhyInfo->SignalQuality = SQ; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_A] = SQ; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_B] = -1; + } + } + else //is OFDM rate + { + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++; + + // + // (1)Get RSSI for HT rate + // + + for(i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) + { + // 2008/01/30 MH we will judge RF RX path now. + if (pDM_Odm->RFPathRxEnable & BIT(i)) + rf_rx_num++; + //else + //continue; + + rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain& 0x3F)*2) - 110; + + + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->RxPwr[i] = rx_pwr[i]; + #endif + + /* Translate DBM to percentage. */ + RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]); + total_rssi += RSSI; + //RT_DISP(FRX, RX_PHY_SS, ("RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI)); + + //Modification for ext-LNA board + if(pDM_Odm->SupportICType&ODM_RTL8192C) + { + if(pDM_Odm->BoardType & (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_PA)) + { + if((pPhyStaRpt->path_agc[i].trsw) == 1) + RSSI = (RSSI>94)?100:(RSSI +6); + else + RSSI = (RSSI<=16)?(RSSI>>3):(RSSI -16); + + if((RSSI <= 34) && (RSSI >=4)) + RSSI -= 4; + } + } + + pPhyInfo->RxMIMOSignalStrength[i] =(u1Byte) RSSI; + + #if (DM_ODM_SUPPORT_TYPE & (/*ODM_WIN|*/ODM_CE|ODM_AP|ODM_ADSL)) + //Get Rx snr value in DB + pPhyInfo->RxSNR[i] = pDM_Odm->PhyDbgInfo.RxSNRdB[i] = (s4Byte)(pPhyStaRpt->path_rxsnr[i]/2); + #endif + + /* Record Signal Strength for next packet */ + //if(pPktinfo->bPacketMatchBSSID) + { + if((pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->PatchID==RT_CID_819x_Lenovo)) + { + if(i==ODM_RF_PATH_A) + pPhyInfo->SignalQuality = odm_SQ_process_patch_RT_CID_819x_Lenovo(pDM_Odm,isCCKrate,PWDB_ALL,i,RSSI); + + } + else if((pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->PatchID==RT_CID_819x_Acer)) + { + pPhyInfo->SignalQuality = odm_SQ_process_patch_RT_CID_819x_Acer(pDM_Odm,isCCKrate,PWDB_ALL,0,RSSI); + } + + } + } + + + // + // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) + // + rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1 )& 0x7f) -110; + + PWDB_ALL_BT = PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + //RT_DISP(FRX, RX_PHY_SS, ("PWDB_ALL=%d\n",PWDB_ALL)); + + pPhyInfo->RxPWDBAll = PWDB_ALL; + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("ODM OFDM RSSI=%d\n",pPhyInfo->RxPWDBAll)); + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT; + pPhyInfo->RxPower = rx_pwr_all; + pPhyInfo->RecvSignalPower = rx_pwr_all; + #endif + + if((pDM_Odm->SupportPlatform == ODM_WIN) &&(pDM_Odm->PatchID==19)){ + //do nothing + }else if((pDM_Odm->SupportPlatform == ODM_WIN) &&(pDM_Odm->PatchID==25)){ + //do nothing + } + else{//pMgntInfo->CustomerID != RT_CID_819x_Lenovo + // + // (3)EVM of HT rate + // + if(pPktinfo->DataRate >=DESC_RATEMCS8 && pPktinfo->DataRate <=DESC_RATEMCS15) + Max_spatial_stream = 2; //both spatial stream make sense + else + Max_spatial_stream = 1; //only spatial stream 1 makes sense + + for(i=0; i>= 1" because the compilor of free build environment + // fill most significant bit to "zero" when doing shifting operation which may change a negative + // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. + EVM = odm_EVMdbToPercentage( (pPhyStaRpt->stream_rxevm[i] )); //dbm + + //RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n", + //GET_RX_STATUS_DESC_RX_MCS(pDesc), pDrvInfo->rxevm[i], "%", EVM)); + + //if(pPktinfo->bPacketMatchBSSID) + { + if(i==ODM_RF_PATH_A) // Fill value in RFD, Get the first spatial stream only + { + pPhyInfo->SignalQuality = (u1Byte)(EVM & 0xff); + } + pPhyInfo->RxMIMOSignalQuality[i] = (u1Byte)(EVM & 0xff); + } + } + } + + ODM_ParsingCFO(pDM_Odm, pPktinfo, pPhyStaRpt->path_cfotail); + + } +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + //UI BSS List signal strength(in percentage), make it good looking, from 0~100. + //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). + if(isCCKrate) + { +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + // 2012/01/12 MH Use customeris signal strength from HalComRxdDesc.c/ + pPhyInfo->SignalStrength = (u1Byte)(SignalScaleMapping(pDM_Odm->Adapter, PWDB_ALL));//PWDB_ALL; +#else +#ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING + pPhyInfo->SignalStrength = (u1Byte)PWDB_ALL; +#else + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, PWDB_ALL));//PWDB_ALL; +#endif +#endif + } + else + { + if (rf_rx_num != 0) + { +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + // 2012/01/12 MH Use customeris signal strength from HalComRxdDesc.c/ + pPhyInfo->SignalStrength = (u1Byte)(SignalScaleMapping(pDM_Odm->Adapter, total_rssi/=rf_rx_num));//PWDB_ALL; +#else +#ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING + total_rssi/=rf_rx_num; + pPhyInfo->SignalStrength = (u1Byte)total_rssi; +#else + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, total_rssi/=rf_rx_num)); +#endif +#endif + } + } +#endif + + //DbgPrint("isCCKrate = %d, pPhyInfo->RxPWDBAll = %d, pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a = 0x%x\n", + //isCCKrate, pPhyInfo->RxPWDBAll, pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a); + + //For 92C/92D HW (Hybrid) Antenna Diversity +#if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) + pDM_SWAT_Table->antsel = pPhyStaRpt->ant_sel; + //For 88E HW Antenna Diversity + pDM_Odm->DM_FatTable.antsel_rx_keep_0 = pPhyStaRpt->ant_sel; + pDM_Odm->DM_FatTable.antsel_rx_keep_1 = pPhyStaRpt->ant_sel_b; + pDM_Odm->DM_FatTable.antsel_rx_keep_2 = pPhyStaRpt->antsel_rx_keep_2; +#endif +} +#endif + + +#if ODM_IC_11AC_SERIES_SUPPORT + +VOID +odm_RxPhyStatusJaguarSeries_Parsing( + IN OUT PDM_ODM_T pDM_Odm, + OUT PODM_PHY_INFO_T pPhyInfo, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ + u1Byte i, Max_spatial_stream; + s1Byte rx_pwr[4], rx_pwr_all=0; + u1Byte EVM = 0, EVMdbm, PWDB_ALL = 0, PWDB_ALL_BT; + u1Byte RSSI, total_rssi=0; + u1Byte isCCKrate=0; + u1Byte rf_rx_num = 0; + u1Byte cck_highpwr = 0; + u1Byte LNA_idx, VGA_idx; + + + PPHY_STATUS_RPT_8812_T pPhyStaRpt = (PPHY_STATUS_RPT_8812_T)pPhyStatus; + + if(pPktinfo->DataRate <= DESC_RATE54M) + { + switch(pPhyStaRpt->r_RFMOD){ + case 1: + if(pPhyStaRpt->sub_chnl == 0) + pPhyInfo->BandWidth = 1; + else + pPhyInfo->BandWidth = 0; + break; + + case 2: + if(pPhyStaRpt->sub_chnl == 0) + pPhyInfo->BandWidth = 2; + else if(pPhyStaRpt->sub_chnl == 9 || pPhyStaRpt->sub_chnl == 10) + pPhyInfo->BandWidth = 1; + else + pPhyInfo->BandWidth = 0; + break; + + default: case 0: + pPhyInfo->BandWidth = 0; + break; + } + } + + if(pPktinfo->DataRate <= DESC_RATE11M) + isCCKrate = TRUE; + else + isCCKrate = FALSE; + + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_A] = -1; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_B] = -1; + + + if(isCCKrate) + { + u1Byte cck_agc_rpt; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK++; + // + // (1)Hardware does not provide RSSI for CCK + // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) + // + + //if(pHalData->eRFPowerState == eRfOn) + cck_highpwr = pDM_Odm->bCckHighPower; + //else + // cck_highpwr = FALSE; + + cck_agc_rpt = pPhyStaRpt->cfosho[0] ; + LNA_idx = ((cck_agc_rpt & 0xE0) >>5); + VGA_idx = (cck_agc_rpt & 0x1F); + + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + switch(LNA_idx) + { + case 7: + if(VGA_idx <= 27) + rx_pwr_all = -100 + 2*(27-VGA_idx); //VGA_idx = 27~2 + else + rx_pwr_all = -100; + break; + case 6: + rx_pwr_all = -48 + 2*(2-VGA_idx); //VGA_idx = 2~0 + break; + case 5: + rx_pwr_all = -42 + 2*(7-VGA_idx); //VGA_idx = 7~5 + break; + case 4: + rx_pwr_all = -36 + 2*(7-VGA_idx); //VGA_idx = 7~4 + break; + case 3: + //rx_pwr_all = -28 + 2*(7-VGA_idx); //VGA_idx = 7~0 + rx_pwr_all = -24 + 2*(7-VGA_idx); //VGA_idx = 7~0 + break; + case 2: + if(cck_highpwr) + rx_pwr_all = -12 + 2*(5-VGA_idx); //VGA_idx = 5~0 + else + rx_pwr_all = -6+ 2*(5-VGA_idx); + break; + case 1: + rx_pwr_all = 8-2*VGA_idx; + break; + case 0: + rx_pwr_all = 14-2*VGA_idx; + break; + default: + //DbgPrint("CCK Exception default\n"); + break; + } + rx_pwr_all += 6; + PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + + if(cck_highpwr == FALSE) + { + if(PWDB_ALL >= 80) + PWDB_ALL = ((PWDB_ALL-80)<<1)+((PWDB_ALL-80)>>1)+80; + else if((PWDB_ALL <= 78) && (PWDB_ALL >= 20)) + PWDB_ALL += 3; + if(PWDB_ALL>100) + PWDB_ALL = 100; + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8821) + { + s1Byte Pout = -6; + + switch(LNA_idx) + { + case 5: + rx_pwr_all = Pout -32 -(2*VGA_idx); + break; + case 4: + rx_pwr_all = Pout -24 -(2*VGA_idx); + break; + case 2: + rx_pwr_all = Pout -11 -(2*VGA_idx); + break; + case 1: + rx_pwr_all = Pout + 5 -(2*VGA_idx); + break; + case 0: + rx_pwr_all = Pout + 21 -(2*VGA_idx); + break; + } + PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + } + + pPhyInfo->RxPWDBAll = PWDB_ALL; + //if(pPktinfo->StationID == 0) + //{ + // DbgPrint("CCK: LNA_idx = %d, VGA_idx = %d, pPhyInfo->RxPWDBAll = %d\n", + // LNA_idx, VGA_idx, pPhyInfo->RxPWDBAll); + //} +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->BTRxRSSIPercentage = PWDB_ALL; + pPhyInfo->RecvSignalPower = rx_pwr_all; +#endif + // + // (3) Get Signal Quality (EVM) + // + //if(pPktinfo->bPacketMatchBSSID) + { + u1Byte SQ,SQ_rpt; + + if((pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->PatchID==RT_CID_819x_Lenovo)) + { + SQ = odm_SQ_process_patch_RT_CID_819x_Lenovo(pDM_Odm,isCCKrate,PWDB_ALL,0,0); + } + else if(pPhyInfo->RxPWDBAll > 40 && !pDM_Odm->bInHctTest) + { + SQ = 100; + } + else + { + SQ_rpt = pPhyStaRpt->pwdb_all; + + if(SQ_rpt > 64) + SQ = 0; + else if (SQ_rpt < 20) + SQ = 100; + else + SQ = ((64-SQ_rpt) * 100) / 44; + + } + + //DbgPrint("cck SQ = %d\n", SQ); + pPhyInfo->SignalQuality = SQ; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_A] = SQ; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_B] = -1; + } + } + else //is OFDM rate + { + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++; + + // + // (1)Get RSSI for OFDM rate + // + + for(i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) + { + // 2008/01/30 MH we will judge RF RX path now. + //DbgPrint("pDM_Odm->RFPathRxEnable = %x\n", pDM_Odm->RFPathRxEnable); + if (pDM_Odm->RFPathRxEnable & BIT(i)) + { + rf_rx_num++; + } + //else + //continue; + //2012.05.25 LukeLee: Testchip AGC report is wrong, it should be restored back to old formula in MP chip + //if((pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8821)) && (!pDM_Odm->bIsMPChip)) + rx_pwr[i] = (pPhyStaRpt->gain_trsw[i]&0x7F) - 110; + //else + // rx_pwr[i] = ((pPhyStaRpt->gain_trsw[i]& 0x3F)*2) - 110; //OLD FORMULA + + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->RxPwr[i] = rx_pwr[i]; + #endif + + /* Translate DBM to percentage. */ + RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]); + + total_rssi += RSSI; + //RT_DISP(FRX, RX_PHY_SS, ("RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI)); + + + + pPhyInfo->RxMIMOSignalStrength[i] =(u1Byte) RSSI; + + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_ADSL)) + //Get Rx snr value in DB + pPhyInfo->RxSNR[i] = pDM_Odm->PhyDbgInfo.RxSNRdB[i] = pPhyStaRpt->rxsnr[i]/2; + #endif + + // + // (2) CFO_short & CFO_tail + // + pPhyInfo->Cfo_short[i] = odm_Cfo( (pPhyStaRpt->cfosho[i]) ); + pPhyInfo->Cfo_tail[i] = odm_Cfo( (pPhyStaRpt->cfotail[i]) ); + + /* Record Signal Strength for next packet */ + //if(pPktinfo->bPacketMatchBSSID) + { + if((pDM_Odm->SupportPlatform == ODM_WIN) && + (pDM_Odm->PatchID==RT_CID_819x_Lenovo)) + { + if(i==ODM_RF_PATH_A) + pPhyInfo->SignalQuality = odm_SQ_process_patch_RT_CID_819x_Lenovo(pDM_Odm,isCCKrate,PWDB_ALL,i,RSSI); + + } + } + } + + + // + // (3)PWDB, Average PWDB cacluated by hardware (for rate adaptive) + // + //2012.05.25 LukeLee: Testchip AGC report is wrong, it should be restored back to old formula in MP chip + if((pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8821)) && (!pDM_Odm->bIsMPChip)) + rx_pwr_all = (pPhyStaRpt->pwdb_all& 0x7f) -110; + else + rx_pwr_all = (((pPhyStaRpt->pwdb_all) >> 1 )& 0x7f) -110; //OLD FORMULA + + PWDB_ALL_BT = PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + + pPhyInfo->RxPWDBAll = PWDB_ALL; + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("ODM OFDM RSSI=%d\n",pPhyInfo->RxPWDBAll)); + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT; + pPhyInfo->RxPower = rx_pwr_all; + pPhyInfo->RecvSignalPower = rx_pwr_all; + #endif + + //DbgPrint("OFDM: pPhyInfo->RxPWDBAll = %d, pPhyInfo->RxMIMOSignalStrength[0] = %d, pPhyInfo->RxMIMOSignalStrength[1] = %d\n", + // pPhyInfo->RxPWDBAll, pPhyInfo->RxMIMOSignalStrength[0], pPhyInfo->RxMIMOSignalStrength[1]); + + + if((pDM_Odm->SupportPlatform == ODM_WIN) &&(pDM_Odm->PatchID==19)) + { + //do nothing + } + else + { //pMgntInfo->CustomerID != RT_CID_819x_Lenovo + // + // (4)EVM of OFDM rate + // + if( (pPktinfo->DataRate>=DESC_RATEMCS8) && + (pPktinfo->DataRate <=DESC_RATEMCS15)) + Max_spatial_stream = 2; + else if( (pPktinfo->DataRate>=DESC_RATEVHTSS2MCS0) && + (pPktinfo->DataRate <=DESC_RATEVHTSS2MCS9)) + Max_spatial_stream = 2; + else + Max_spatial_stream = 1; + + //if(pPktinfo->bPacketMatchBSSID) + { + //DbgPrint("pPktinfo->DataRate = %d\n", pPktinfo->DataRate); + + for(i=0; i>= 1" because the compilor of free build environment + // fill most significant bit to "zero" when doing shifting operation which may change a negative + // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. + // + // 2013/09/02 MH According to 8812AU test, when use RX evm the value sometimes + // will be incorrect and 1SS-MCS-0-7 always incorrect. Only use LSIG the evm value + // seems ok. This seems BB bug, we need use another way to display better SQ. + // + //if (pPktinfo->DataRate>=DESC8812_RATE6M && pPktinfo->DataRate<=DESC8812_RATE54M) + { + + if(i==ODM_RF_PATH_A ) + { + EVM = odm_EVMdbToPercentage( (pPhyStaRpt->sigevm )); //dbm + EVM += 20; + if (EVM > 100) + EVM = 100; + } + } +#if 0 + else + { + if (pPhyStaRpt->rxevm[i] == -128) + { + pPhyStaRpt->rxevm[i] = -25; + } + EVM = odm_EVMdbToPercentage( (pPhyStaRpt->rxevm[i] )); //dbm + } +#endif + EVMdbm = odm_EVMdbm_JaguarSeries(pPhyStaRpt->rxevm[i]); + //RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n", + //pPktinfo->DataRate, pPhyStaRpt->rxevm[i], "%", EVM)); + + { + if(i==ODM_RF_PATH_A) // Fill value in RFD, Get the first spatial stream only + { + pPhyInfo->SignalQuality = EVM; + } + pPhyInfo->RxMIMOSignalQuality[i] = EVM; + pPhyInfo->RxMIMOEVMdbm[i] = EVMdbm; + } + } + } + } + + ODM_ParsingCFO(pDM_Odm, pPktinfo, pPhyStaRpt->cfotail); + + } + //DbgPrint("isCCKrate= %d, pPhyInfo->SignalStrength=%d % PWDB_AL=%d rf_rx_num=%d\n", isCCKrate, pPhyInfo->SignalStrength, PWDB_ALL, rf_rx_num); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + //UI BSS List signal strength(in percentage), make it good looking, from 0~100. + //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). + if(isCCKrate) + { +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + // 2012/01/12 MH Use customeris signal strength from HalComRxdDesc.c/ + pPhyInfo->SignalStrength = (u1Byte)(SignalScaleMapping(pDM_Odm->Adapter, PWDB_ALL));//PWDB_ALL; +#else + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, PWDB_ALL));//PWDB_ALL; +#endif + } + else + { + if (rf_rx_num != 0) + { +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + // 2012/01/12 MH Use customeris signal strength from HalComRxdDesc.c/ + pPhyInfo->SignalStrength = (u1Byte)(SignalScaleMapping(pDM_Odm->Adapter, total_rssi/=rf_rx_num));//PWDB_ALL; +#else + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, total_rssi/=rf_rx_num)); +#endif + } + } +#endif + pDM_Odm->RxPWDBAve = pDM_Odm->RxPWDBAve + pPhyInfo->RxPWDBAll; + + pDM_Odm->DM_FatTable.antsel_rx_keep_0 = pPhyStaRpt->antidx_anta; + pDM_Odm->DM_FatTable.antsel_rx_keep_1 = pPhyStaRpt->antidx_antb; + + //DbgPrint("pPhyStaRpt->antidx_anta = %d, pPhyStaRpt->antidx_antb = %d, pPhyStaRpt->resvd_1 = %d", + // pPhyStaRpt->antidx_anta, pPhyStaRpt->antidx_antb, pPhyStaRpt->resvd_1); + + //DbgPrint("----------------------------\n"); + //DbgPrint("pPktinfo->StationID=%d, pPktinfo->DataRate=0x%x\n",pPktinfo->StationID, pPktinfo->DataRate); + //DbgPrint("pPhyStaRpt->gain_trsw[0]=0x%x, pPhyStaRpt->gain_trsw[1]=0x%x, pPhyStaRpt->pwdb_all=0x%x\n", + // pPhyStaRpt->gain_trsw[0],pPhyStaRpt->gain_trsw[1], pPhyStaRpt->pwdb_all); + //DbgPrint("pPhyInfo->RxMIMOSignalStrength[0]=%d, pPhyInfo->RxMIMOSignalStrength[1]=%d, RxPWDBAll=%d\n", + // pPhyInfo->RxMIMOSignalStrength[0], pPhyInfo->RxMIMOSignalStrength[1], pPhyInfo->RxPWDBAll); + +} + +#endif + +VOID +odm_Init_RSSIForDM( + IN OUT PDM_ODM_T pDM_Odm + ) +{ + +} + +VOID +odm_Process_RSSIForDM( + IN OUT PDM_ODM_T pDM_Odm, + IN PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ + + s4Byte UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK, UndecoratedSmoothedOFDM, RSSI_Ave; + u1Byte i, isCCKrate=0; + u1Byte RSSI_max, RSSI_min; + u4Byte OFDM_pkt=0; + u4Byte Weighting=0; + PSTA_INFO_T pEntry; + + if(pPktinfo->StationID == 0xFF) + return; + +#if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + odm_S0S1_SwAntDivByCtrlFrame_ProcessRSSI(pDM_Odm, pPhyInfo, pPktinfo); +#endif +#endif + + // + // 2012/05/30 MH/Luke.Lee Add some description + // In windows driver: AP/IBSS mode STA + // + //if (pDM_Odm->SupportPlatform == ODM_WIN) + //{ + // pEntry = pDM_Odm->pODM_StaInfo[pDM_Odm->pAidMap[pPktinfo->StationID-1]]; + //} + //else + pEntry = pDM_Odm->pODM_StaInfo[pPktinfo->StationID]; + + if(!IS_STA_VALID(pEntry) ) + { + return; + } + + if((!pPktinfo->bPacketMatchBSSID) ) + { + return; + } + + if(pPktinfo->bPacketBeacon) + pDM_Odm->PhyDbgInfo.NumQryBeaconPkt++; + + isCCKrate = (pPktinfo->DataRate <= DESC_RATE11M)?TRUE :FALSE; + pDM_Odm->RxRate = pPktinfo->DataRate; + /* + if(!isCCKrate) + { + DbgPrint("OFDM: pPktinfo->StationID=%d, isCCKrate=%d, pPhyInfo->RxPWDBAll=%d\n", + pPktinfo->StationID, isCCKrate, pPhyInfo->RxPWDBAll); + } + */ + + //--------------Statistic for antenna/path diversity------------------ + if(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) + { + #if(defined(CONFIG_HW_ANTENNA_DIVERSITY)) + ODM_Process_RSSIForAntDiv(pDM_Odm,pPhyInfo,pPktinfo); + #endif + } + else if(pDM_Odm->SupportAbility & ODM_BB_PATH_DIV) + { + #if (RTL8812A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + pPATHDIV_T pDM_PathDiv = &pDM_Odm->DM_PathDiv; + if(pPktinfo->bPacketToSelf || pPktinfo->bPacketMatchBSSID) + { + if(pPktinfo->DataRate > DESC_RATE11M) + ODM_PathStatistics_8812A(pDM_Odm, pPktinfo->StationID, pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A], + pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]); + } + } + #endif + } + + //-----------------Smart Antenna Debug Message------------------// + + UndecoratedSmoothedCCK = pEntry->rssi_stat.UndecoratedSmoothedCCK; + UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM; + UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; + + if(pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) + { + + if(!isCCKrate)//ofdm rate + { + if(pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B] == 0) + { + RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]; + pDM_Odm->RSSI_A = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]; + pDM_Odm->RSSI_B = 0; + } + else + { + //DbgPrint("pRfd->Status.RxMIMOSignalStrength[0] = %d, pRfd->Status.RxMIMOSignalStrength[1] = %d \n", + //pRfd->Status.RxMIMOSignalStrength[0], pRfd->Status.RxMIMOSignalStrength[1]); + pDM_Odm->RSSI_A = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]; + pDM_Odm->RSSI_B = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]; + + if(pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]) + { + RSSI_max = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]; + RSSI_min = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]; + } + else + { + RSSI_max = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]; + RSSI_min = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]; + } + if((RSSI_max -RSSI_min) < 3) + RSSI_Ave = RSSI_max; + else if((RSSI_max -RSSI_min) < 6) + RSSI_Ave = RSSI_max - 1; + else if((RSSI_max -RSSI_min) < 10) + RSSI_Ave = RSSI_max - 2; + else + RSSI_Ave = RSSI_max - 3; + } + + //1 Process OFDM RSSI + if(UndecoratedSmoothedOFDM <= 0) // initialize + { + UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll; + } + else + { + if(pPhyInfo->RxPWDBAll > (u4Byte)UndecoratedSmoothedOFDM) + { + UndecoratedSmoothedOFDM = + ( ((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) + + (RSSI_Ave)) /(Rx_Smooth_Factor); + UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1; + } + else + { + UndecoratedSmoothedOFDM = + ( ((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) + + (RSSI_Ave)) /(Rx_Smooth_Factor); + } + } + + pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap<<1) | BIT0; + + } + else + { + RSSI_Ave = pPhyInfo->RxPWDBAll; + pDM_Odm->RSSI_A = (u1Byte) pPhyInfo->RxPWDBAll; + pDM_Odm->RSSI_B = 0; + + //1 Process CCK RSSI + if(UndecoratedSmoothedCCK <= 0) // initialize + { + UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll; + } + else + { + if(pPhyInfo->RxPWDBAll > (u4Byte)UndecoratedSmoothedCCK) + { + UndecoratedSmoothedCCK = + ( ((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) + + (pPhyInfo->RxPWDBAll)) /(Rx_Smooth_Factor); + UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1; + } + else + { + UndecoratedSmoothedCCK = + ( ((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) + + (pPhyInfo->RxPWDBAll)) /(Rx_Smooth_Factor); + } + } + pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap<<1; + } + + //if(pEntry) + { + //2011.07.28 LukeLee: modified to prevent unstable CCK RSSI + if(pEntry->rssi_stat.ValidBit >= 64) + pEntry->rssi_stat.ValidBit = 64; + else + pEntry->rssi_stat.ValidBit++; + + for(i=0; irssi_stat.ValidBit; i++) + OFDM_pkt += (u1Byte)(pEntry->rssi_stat.PacketMap>>i)&BIT0; + + if(pEntry->rssi_stat.ValidBit == 64) + { + Weighting = ((OFDM_pkt<<4) > 64)?64:(OFDM_pkt<<4); + UndecoratedSmoothedPWDB = (Weighting*UndecoratedSmoothedOFDM+(64-Weighting)*UndecoratedSmoothedCCK)>>6; + } + else + { + if(pEntry->rssi_stat.ValidBit != 0) + UndecoratedSmoothedPWDB = (OFDM_pkt*UndecoratedSmoothedOFDM+(pEntry->rssi_stat.ValidBit-OFDM_pkt)*UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit; + else + UndecoratedSmoothedPWDB = 0; + } + + pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK; + pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM; + pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; + + //DbgPrint("OFDM_pkt=%d, Weighting=%d\n", OFDM_pkt, Weighting); + //DbgPrint("UndecoratedSmoothedOFDM=%d, UndecoratedSmoothedPWDB=%d, UndecoratedSmoothedCCK=%d\n", + // UndecoratedSmoothedOFDM, UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK); + + } + + } +} + + +#if(ODM_IC_11N_SERIES_SUPPORT ==1) +// +// Endianness before calling this API +// +VOID +ODM_PhyStatusQuery_92CSeries( + IN OUT PDM_ODM_T pDM_Odm, + OUT PODM_PHY_INFO_T pPhyInfo, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ + + odm_RxPhyStatus92CSeries_Parsing( + pDM_Odm, + pPhyInfo, + pPhyStatus, + pPktinfo); + + if( pDM_Odm->RSSI_test == TRUE) + { + // Select the packets to do RSSI checking for antenna switching. + if(pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon ) + { + /* + #if 0//(DM_ODM_SUPPORT_TYPE == ODM_WIN) + dm_SWAW_RSSI_Check( + Adapter, + (tmppAdapter!=NULL)?(tmppAdapter==Adapter):TRUE, + bPacketMatchBSSID, + pEntry, + pRfd); + #elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + // Select the packets to do RSSI checking for antenna switching. + //odm_SwAntDivRSSICheck8192C(padapter, precvframe->u.hdr.attrib.RxPWDBAll); + #endif + */ +#if (RTL8192C_SUPPORT == 1) + ODM_SwAntDivChkPerPktRssi(pDM_Odm,pPktinfo->StationID,pPhyInfo); +#endif + } + } + else + { + odm_Process_RSSIForDM(pDM_Odm,pPhyInfo,pPktinfo); + } + +} +#endif + +#if(ODM_IC_11AC_SERIES_SUPPORT == 1) +// +// Endianness before calling this API +// +VOID +ODM_PhyStatusQuery_JaguarSeries( + IN OUT PDM_ODM_T pDM_Odm, + OUT PODM_PHY_INFO_T pPhyInfo, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ + + odm_RxPhyStatusJaguarSeries_Parsing( + pDM_Odm, + pPhyInfo, + pPhyStatus, + pPktinfo); + + odm_Process_RSSIForDM(pDM_Odm,pPhyInfo,pPktinfo); + +} +#endif + + +VOID +ODM_PhyStatusQuery( + IN OUT PDM_ODM_T pDM_Odm, + OUT PODM_PHY_INFO_T pPhyInfo, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ +#if(ODM_IC_11AC_SERIES_SUPPORT == 1) + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES ) + ODM_PhyStatusQuery_JaguarSeries(pDM_Odm,pPhyInfo,pPhyStatus,pPktinfo); +#endif + +#if(ODM_IC_11N_SERIES_SUPPORT ==1) + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES ) + ODM_PhyStatusQuery_92CSeries(pDM_Odm,pPhyInfo,pPhyStatus,pPktinfo); +#endif +} + +// For future use. +VOID +ODM_MacStatusQuery( + IN OUT PDM_ODM_T pDM_Odm, + IN pu1Byte pMacStatus, + IN u1Byte MacID, + IN BOOLEAN bPacketMatchBSSID, + IN BOOLEAN bPacketToSelf, + IN BOOLEAN bPacketBeacon + ) +{ + // 2011/10/19 Driver team will handle in the future. + +} + + +// +// If you want to add a new IC, Please follow below template and generate a new one. +// +// + +HAL_STATUS +ODM_ConfigRFWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_Config_Type ConfigType, + IN ODM_RF_RADIO_PATH_E eRFPath + ) +{ + PADAPTER Adapter = pDM_Odm->Adapter; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("===>ODM_ConfigRFWithHeaderFile (%s)\n", (pDM_Odm->bIsMPChip) ? "MPChip" : "TestChip")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("pDM_Odm->SupportPlatform: 0x%X, pDM_Odm->SupportInterface: 0x%X, pDM_Odm->BoardType: 0x%X\n", + pDM_Odm->SupportPlatform, pDM_Odm->SupportInterface, pDM_Odm->BoardType)); + +#if (RTL8723A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723A) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8723A,_RadioA); + } + } +#endif + +#if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8188E,_RadioA); + } + else if(ConfigType == CONFIG_RF_TXPWR_LMT) { + READ_AND_CONFIG_MP(8188E,_TXPWR_LMT); + } + } +#endif + +#if (RTL8812A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8812) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + { + READ_AND_CONFIG_MP(8812A,_RadioA); + } + else if(eRFPath == ODM_RF_PATH_B) + { + READ_AND_CONFIG_MP(8812A,_RadioB); + } + } + else if(ConfigType == CONFIG_RF_TXPWR_LMT) { + READ_AND_CONFIG_MP(8812A,_TXPWR_LMT); + } + } +#endif + +#if (RTL8821A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + { + READ_AND_CONFIG_MP(8821A,_RadioA); + } + } + else if(ConfigType == CONFIG_RF_TXPWR_LMT) { + + if (pDM_Odm->SupportInterface == ODM_ITRF_USB) { + if (pDM_Odm->ExtPA5G || pDM_Odm->ExtLNA5G) + READ_AND_CONFIG_MP(8821A,_TXPWR_LMT_8811AU_FEM); + else + READ_AND_CONFIG_MP(8821A,_TXPWR_LMT_8811AU_IPA); + } else { + READ_AND_CONFIG_MP(8821A,_TXPWR_LMT_8821A); + } + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("<===8821_ODM_ConfigRFWithHeaderFile\n")); + } +#endif + +#if (RTL8723B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723B) + { + if(ConfigType == CONFIG_RF_RADIO) { + READ_AND_CONFIG_MP(8723B,_RadioA); + } + else if(ConfigType == CONFIG_RF_TXPWR_LMT) { + READ_AND_CONFIG_MP(8723B,_TXPWR_LMT); + } + } +#endif + +#if (RTL8192E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8192E) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8192E,_RadioA); + else if(eRFPath == ODM_RF_PATH_B) + READ_AND_CONFIG_MP(8192E,_RadioB); + } + else if(ConfigType == CONFIG_RF_TXPWR_LMT) { + READ_AND_CONFIG_MP(8192E,_TXPWR_LMT); + } + } +#endif + +#if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8814A) + { + /* + if(ConfigType == CONFIG_RF_TXPWR_LMT) { + READ_AND_CONFIG(8813A,_TXPWR_LMT); + } + */ + } +#endif + + return HAL_STATUS_SUCCESS; +} + +HAL_STATUS +ODM_ConfigRFWithTxPwrTrackHeaderFile( + IN PDM_ODM_T pDM_Odm + ) +{ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("===>ODM_ConfigRFWithTxPwrTrackHeaderFile (%s)\n", (pDM_Odm->bIsMPChip) ? "MPChip" : "TestChip")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("pDM_Odm->SupportPlatform: 0x%X, pDM_Odm->SupportInterface: 0x%X, pDM_Odm->BoardType: 0x%X\n", + pDM_Odm->SupportPlatform, pDM_Odm->SupportInterface, pDM_Odm->BoardType)); + if(0) + { + } +#if (RTL8821A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8821) + { + if (pDM_Odm->SupportInterface == ODM_ITRF_PCIE) + READ_AND_CONFIG_MP(8821A,_TxPowerTrack_PCIE); + else if (pDM_Odm->SupportInterface == ODM_ITRF_USB) + READ_AND_CONFIG_MP(8821A,_TxPowerTrack_USB); + else + READ_AND_CONFIG_MP(8821A,_TxPowerTrack_PCIE); + } +#endif +#if (RTL8812A_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8812) + { + if (pDM_Odm->SupportInterface == ODM_ITRF_PCIE) + READ_AND_CONFIG_MP(8812A,_TxPowerTrack_PCIE); + else if (pDM_Odm->SupportInterface == ODM_ITRF_USB) { + if (pDM_Odm->RFEType == 3 && pDM_Odm->bIsMPChip) + READ_AND_CONFIG_MP(8812A,_TxPowerTrack_RFE3); + else + READ_AND_CONFIG_MP(8812A,_TxPowerTrack_USB); + } + + } +#endif +#if (RTL8192E_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + if (pDM_Odm->SupportInterface == ODM_ITRF_PCIE) + READ_AND_CONFIG_MP(8192E,_TxPowerTrack_PCIE); + else if (pDM_Odm->SupportInterface == ODM_ITRF_USB) + READ_AND_CONFIG_MP(8192E,_TxPowerTrack_USB); + } +#endif +#if RTL8723B_SUPPORT + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + if (pDM_Odm->SupportInterface == ODM_ITRF_PCIE) + READ_AND_CONFIG_MP(8723B,_TxPowerTrack_PCIE); + else if (pDM_Odm->SupportInterface == ODM_ITRF_USB) + READ_AND_CONFIG_MP(8723B,_TxPowerTrack_USB); + else if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO) + READ_AND_CONFIG_MP(8723B,_TxPowerTrack_SDIO); + } +#endif +#if RTL8188E_SUPPORT + else if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + if (pDM_Odm->SupportInterface == ODM_ITRF_PCIE) + READ_AND_CONFIG_MP(8188E,_TxPowerTrack_PCIE); + else if (pDM_Odm->SupportInterface == ODM_ITRF_USB) + READ_AND_CONFIG_MP(8188E,_TxPowerTrack_USB); + else + READ_AND_CONFIG_MP(8188E,_TxPowerTrack_PCIE); + } +#endif + + return HAL_STATUS_SUCCESS; +} + +HAL_STATUS +ODM_ConfigBBWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_BB_Config_Type ConfigType + ) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); +#endif +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("===>ODM_ConfigBBWithHeaderFile (%s)\n", (pDM_Odm->bIsMPChip) ? "MPChip" : "TestChip")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("pDM_Odm->SupportPlatform: 0x%X, pDM_Odm->SupportInterface: 0x%X, pDM_Odm->BoardType: 0x%X\n", + pDM_Odm->SupportPlatform, pDM_Odm->SupportInterface, pDM_Odm->BoardType)); + +#if (RTL8723A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8723A) + { + if(ConfigType == CONFIG_BB_PHY_REG) + { + READ_AND_CONFIG_MP(8723A,_PHY_REG); + } + else if(ConfigType == CONFIG_BB_AGC_TAB) + { + READ_AND_CONFIG_MP(8723A,_AGC_TAB); + } + } +#endif + +#if (RTL8188E_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + if(ConfigType == CONFIG_BB_PHY_REG) + { + READ_AND_CONFIG_MP(8188E,_PHY_REG); + } + else if(ConfigType == CONFIG_BB_AGC_TAB) + { + READ_AND_CONFIG_MP(8188E,_AGC_TAB); + } + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + { + READ_AND_CONFIG_MP(8188E,_PHY_REG_PG); + } + } +#endif + +#if (RTL8812A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + if(ConfigType == CONFIG_BB_PHY_REG) + { + READ_AND_CONFIG_MP(8812A,_PHY_REG); + } + else if(ConfigType == CONFIG_BB_AGC_TAB) + { + READ_AND_CONFIG_MP(8812A,_AGC_TAB); + } + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + { + if (pDM_Odm->RFEType == 3 && pDM_Odm->bIsMPChip) + READ_AND_CONFIG_MP(8812A,_PHY_REG_PG_ASUS); +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + else if (pMgntInfo->CustomerID == RT_CID_WNC_NEC && pDM_Odm->bIsMPChip) + READ_AND_CONFIG_MP(8812A,_PHY_REG_PG_NEC); +#endif + else + READ_AND_CONFIG_MP(8812A,_PHY_REG_PG); + } + else if(ConfigType == CONFIG_BB_PHY_REG_MP) + { + READ_AND_CONFIG_MP(8812A,_PHY_REG_MP); + } + else if(ConfigType == CONFIG_BB_AGC_TAB_DIFF) + { + if ((36 <= *pDM_Odm->pChannel) && (*pDM_Odm->pChannel <= 64)) + AGC_DIFF_CONFIG_MP(8812A,LB); + else if (100 <= *pDM_Odm->pChannel) + AGC_DIFF_CONFIG_MP(8812A,HB); + } + } +#endif + +#if (RTL8821A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8821) + { + if(ConfigType == CONFIG_BB_PHY_REG) + { + READ_AND_CONFIG_MP(8821A,_PHY_REG); + } + else if(ConfigType == CONFIG_BB_AGC_TAB) + { + READ_AND_CONFIG_MP(8821A,_AGC_TAB); + } + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + { + READ_AND_CONFIG_MP(8821A,_PHY_REG_PG); + } + } +#endif +#if (RTL8723B_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + + if(ConfigType == CONFIG_BB_PHY_REG) + { + READ_AND_CONFIG_MP(8723B,_PHY_REG); + } + else if(ConfigType == CONFIG_BB_AGC_TAB) + { + READ_AND_CONFIG_MP(8723B,_AGC_TAB); + } + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + { + READ_AND_CONFIG_MP(8723B,_PHY_REG_PG); + } + } +#endif +#if (RTL8192E_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + + if(ConfigType == CONFIG_BB_PHY_REG) + { + READ_AND_CONFIG_MP(8192E,_PHY_REG); + } + else if(ConfigType == CONFIG_BB_AGC_TAB) + { + READ_AND_CONFIG_MP(8192E,_AGC_TAB); + } + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + { + READ_AND_CONFIG_MP(8192E,_PHY_REG_PG); + } + } +#endif +#if (RTL8814A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8814A) + { + + if(ConfigType == CONFIG_BB_PHY_REG) + { + READ_AND_CONFIG(8813A,_PHY_REG); + } + else if(ConfigType == CONFIG_BB_AGC_TAB) + { + READ_AND_CONFIG(8813A,_AGC_TAB); + } + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + { + //READ_AND_CONFIG(8813A,_PHY_REG_PG); + } + } +#endif + return HAL_STATUS_SUCCESS; +} + +HAL_STATUS +ODM_ConfigMACWithHeaderFile( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; +#endif + u1Byte result = HAL_STATUS_SUCCESS; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("===>ODM_ConfigMACWithHeaderFile (%s)\n", (pDM_Odm->bIsMPChip) ? "MPChip" : "TestChip")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, + ("pDM_Odm->SupportPlatform: 0x%X, pDM_Odm->SupportInterface: 0x%X, pDM_Odm->BoardType: 0x%X\n", + pDM_Odm->SupportPlatform, pDM_Odm->SupportInterface, pDM_Odm->BoardType)); + +#if (RTL8723A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723A) + { + READ_AND_CONFIG_MP(8723A,_MAC_REG); + } +#endif +#if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + { + READ_AND_CONFIG_MP(8188E,_MAC_REG); + } +#endif +#if (RTL8812A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8812) + { + READ_AND_CONFIG_MP(8812A,_MAC_REG); + } +#endif +#if (RTL8821A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821) + { + READ_AND_CONFIG_MP(8821A,_MAC_REG); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("<===8821_ODM_ConfigMACwithHeaderFile\n")); + } +#endif +#if (RTL8723B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723B) + { + READ_AND_CONFIG_MP(8723B,_MAC_REG); + } +#endif +#if (RTL8192E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8192E) + { + READ_AND_CONFIG_MP(8192E,_MAC_REG); + } +#endif + + return result; +} + +HAL_STATUS +ODM_ConfigFWWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_FW_Config_Type ConfigType, + OUT u1Byte *pFirmware, + OUT u4Byte *pSize + ) +{ + +#if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + { + #ifdef CONFIG_SFW_SUPPORTED + if (ConfigType == CONFIG_FW_NIC) + { + READ_FIRMWARE_MP(8188E,_FW_NIC_T); + } + else if (ConfigType == CONFIG_FW_WoWLAN) + { + READ_FIRMWARE_MP(8188E,_FW_WoWLAN_T); + } + else if(ConfigType == CONFIG_FW_NIC_2) + { + READ_FIRMWARE_MP(8188E,_FW_NIC_S); + } + else if (ConfigType == CONFIG_FW_WoWLAN_2) + { + READ_FIRMWARE_MP(8188E,_FW_WoWLAN_S); + } + #else + if (ConfigType == CONFIG_FW_NIC) + { + READ_FIRMWARE_MP(8188E,_FW_NIC); + } + else if (ConfigType == CONFIG_FW_WoWLAN) + { + READ_FIRMWARE_MP(8188E,_FW_WoWLAN); + } + #endif + } +#endif +#if (RTL8723B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723B) + { + if (ConfigType == CONFIG_FW_NIC) + { + READ_FIRMWARE_MP(8723B,_FW_NIC); + } + else if (ConfigType == CONFIG_FW_WoWLAN) + { + READ_FIRMWARE_MP(8723B,_FW_WoWLAN); + } +#ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP_WoWLAN) + { + READ_FIRMWARE(8723B,_FW_AP_WoWLAN); + } +#endif + else if (ConfigType == CONFIG_FW_BT) + { + READ_FIRMWARE_MP(8723B,_FW_BT); + } + else if (ConfigType == CONFIG_FW_MP) + { + READ_FIRMWARE_MP(8723B,_FW_MP); + } + } +#endif +#if (RTL8812A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8812) + { + if (ConfigType == CONFIG_FW_NIC) + { + READ_FIRMWARE_MP(8812A,_FW_NIC); + } + else if (ConfigType == CONFIG_FW_WoWLAN) + { + READ_FIRMWARE_MP(8812A,_FW_WoWLAN); + } + else if (ConfigType == CONFIG_FW_BT) + { + READ_FIRMWARE_MP(8812A,_FW_NIC_BT); + } + + } +#endif +#if (RTL8821A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821) + { + if (ConfigType == CONFIG_FW_NIC) + { + READ_FIRMWARE_MP(8821A,_FW_NIC); + } + else if (ConfigType == CONFIG_FW_WoWLAN) + { + READ_FIRMWARE_MP(8821A,_FW_WoWLAN); + } + else if (ConfigType == CONFIG_FW_BT) + { + READ_FIRMWARE_MP(8821A,_FW_NIC_BT); + } + } +#endif +#if (RTL8192E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8192E) + { + if (ConfigType == CONFIG_FW_NIC) + { + READ_FIRMWARE_MP(8192E,_FW_NIC); + } + else if (ConfigType == CONFIG_FW_WoWLAN) + { + READ_FIRMWARE_MP(8192E,_FW_WoWLAN); + } +#ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP_WoWLAN) + { + READ_FIRMWARE_MP(8192E,_FW_AP_WoWLAN); + } +#endif + + } +#endif + return HAL_STATUS_SUCCESS; +} + + +u4Byte +ODM_GetHWImgVersion( + IN PDM_ODM_T pDM_Odm + ) +{ + u4Byte Version=0; + +#if (RTL8723A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723A) + Version = GET_VERSION_MP(8723A,_MAC_REG); +#endif + +#if (RTL8723B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723B) + Version = GET_VERSION_MP(8723B,_MAC_REG); +#endif + +#if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + Version = GET_VERSION_MP(8188E,_MAC_REG); +#endif + +#if (RTL8821A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821) + Version = GET_VERSION_MP(8821A,_MAC_REG); +#endif + +#if (RTL8192E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8192E) + Version = GET_VERSION_MP(8192E,_MAC_REG); +#endif + +#if (RTL8812A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8812) + Version = GET_VERSION_MP(8812A,_MAC_REG); +#endif + + return Version; +} + + + + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_HWConfig.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_HWConfig.h new file mode 100755 index 000000000000..da0e5fc1cfce --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_HWConfig.h @@ -0,0 +1,237 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __HALHWOUTSRC_H__ +#define __HALHWOUTSRC_H__ + + +/*--------------------------Define -------------------------------------------*/ +//#define READ_NEXT_PAIR(v1, v2, i) do { i += 2; v1 = Array[i]; v2 = Array[i+1]; } while(0) +#define AGC_DIFF_CONFIG_MP(ic, band) (ODM_ReadAndConfig_MP_##ic##_AGC_TAB_DIFF(pDM_Odm, Array_MP_##ic##_AGC_TAB_DIFF_##band, \ + sizeof(Array_MP_##ic##_AGC_TAB_DIFF_##band)/sizeof(u4Byte))) +#define AGC_DIFF_CONFIG_TC(ic, band) (ODM_ReadAndConfig_TC_##ic##_AGC_TAB_DIFF(pDM_Odm, Array_TC_##ic##_AGC_TAB_DIFF_##band, \ + sizeof(Array_TC_##ic##_AGC_TAB_DIFF_##band)/sizeof(u4Byte))) + +#define AGC_DIFF_CONFIG(ic, band) do {\ + if (pDM_Odm->bIsMPChip)\ + AGC_DIFF_CONFIG_MP(ic,band);\ + else\ + AGC_DIFF_CONFIG_TC(ic,band);\ + } while(0) + + +//============================================================ +// structure and define +//============================================================ + +typedef struct _Phy_Rx_AGC_Info +{ + #if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte gain:7,trsw:1; + #else + u1Byte trsw:1,gain:7; + #endif +} PHY_RX_AGC_INFO_T,*pPHY_RX_AGC_INFO_T; + +typedef struct _Phy_Status_Rpt_8192cd +{ + PHY_RX_AGC_INFO_T path_agc[2]; + u1Byte ch_corr[2]; + u1Byte cck_sig_qual_ofdm_pwdb_all; + u1Byte cck_agc_rpt_ofdm_cfosho_a; + u1Byte cck_rpt_b_ofdm_cfosho_b; + u1Byte rsvd_1;//ch_corr_msb; + u1Byte noise_power_db_msb; + s1Byte path_cfotail[2]; + u1Byte pcts_mask[2]; + s1Byte stream_rxevm[2]; + u1Byte path_rxsnr[2]; + u1Byte noise_power_db_lsb; + u1Byte rsvd_2[3]; + u1Byte stream_csi[2]; + u1Byte stream_target_csi[2]; + s1Byte sig_evm; + u1Byte rsvd_3; + +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antsel_rx_keep_2:1; //ex_intf_flg:1; + u1Byte sgi_en:1; + u1Byte rxsc:2; + u1Byte idle_long:1; + u1Byte r_ant_train_en:1; + u1Byte ant_sel_b:1; + u1Byte ant_sel:1; +#else // _BIG_ENDIAN_ + u1Byte ant_sel:1; + u1Byte ant_sel_b:1; + u1Byte r_ant_train_en:1; + u1Byte idle_long:1; + u1Byte rxsc:2; + u1Byte sgi_en:1; + u1Byte antsel_rx_keep_2:1; //ex_intf_flg:1; +#endif +} PHY_STATUS_RPT_8192CD_T,*PPHY_STATUS_RPT_8192CD_T; + + +typedef struct _Phy_Status_Rpt_8812 +{ +#if 0 + PHY_RX_AGC_INFO_T path_agc[2]; + u1Byte ch_num[2]; + u1Byte cck_sig_qual_ofdm_pwdb_all; + u1Byte cck_agc_rpt_ofdm_cfosho_a; + u1Byte cck_bb_pwr_ofdm_cfosho_b; + u1Byte cck_rx_path; //CCK_RX_PATH [3:0] (with regA07[3:0] definition) + u1Byte rsvd_1; + u1Byte path_cfotail[2]; + u1Byte pcts_mask[2]; + s1Byte stream_rxevm[2]; + u1Byte path_rxsnr[2]; + u1Byte rsvd_2[2]; + u1Byte stream_snr[2]; + u1Byte stream_csi[2]; + u1Byte rsvd_3[2]; + s1Byte sig_evm; + u1Byte rsvd_4; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_anta:3; + u1Byte antidx_antb:3; + u1Byte rsvd_5:2; +#else // _BIG_ENDIAN_ + u1Byte rsvd_5:2; + u1Byte antidx_antb:3; + u1Byte antidx_anta:3; +#endif +#endif + + //2012.05.24 LukeLee: This structure should take big/little endian in consideration later..... + + //DWORD 0 + u1Byte gain_trsw[2]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u2Byte chl_num:10; + u2Byte sub_chnl:4; + u2Byte r_RFMOD:2; +#else // _BIG_ENDIAN_ + u2Byte r_RFMOD:2; + u2Byte sub_chnl:4; + u2Byte chl_num:10; +#endif + + //DWORD 1 + u1Byte pwdb_all; + u1Byte cfosho[4]; // DW 1 byte 1 DW 2 byte 0 + + //DWORD 2 + s1Byte cfotail[4]; // DW 2 byte 1 DW 3 byte 0 + + //DWORD 3 + s1Byte rxevm[2]; // DW 3 byte 1 DW 3 byte 2 + s1Byte rxsnr[2]; // DW 3 byte 3 DW 4 byte 0 + + //DWORD 4 + u1Byte PCTS_MSK_RPT[2]; + u1Byte pdsnr[2]; // DW 4 byte 3 DW 5 Byte 0 + + //DWORD 5 + u1Byte csi_current[2]; + u1Byte rx_gain_c; + + //DWORD 6 + u1Byte rx_gain_d; + s1Byte sigevm; + u1Byte resvd_0; + u1Byte antidx_anta:3; + u1Byte antidx_antb:3; + u1Byte resvd_1:2; +} PHY_STATUS_RPT_8812_T,*PPHY_STATUS_RPT_8812_T; + + +VOID +odm_Init_RSSIForDM( + IN OUT PDM_ODM_T pDM_Odm + ); + +VOID +ODM_PhyStatusQuery( + IN OUT PDM_ODM_T pDM_Odm, + OUT PODM_PHY_INFO_T pPhyInfo, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo + ); + +VOID +ODM_MacStatusQuery( + IN OUT PDM_ODM_T pDM_Odm, + IN pu1Byte pMacStatus, + IN u1Byte MacID, + IN BOOLEAN bPacketMatchBSSID, + IN BOOLEAN bPacketToSelf, + IN BOOLEAN bPacketBeacon + ); +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP)) + +HAL_STATUS +ODM_ConfigRFWithTxPwrTrackHeaderFile( + IN PDM_ODM_T pDM_Odm + ); + +HAL_STATUS +ODM_ConfigRFWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_Config_Type ConfigType, + IN ODM_RF_RADIO_PATH_E eRFPath + ); + +HAL_STATUS +ODM_ConfigBBWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_BB_Config_Type ConfigType + ); + +HAL_STATUS +ODM_ConfigMACWithHeaderFile( + IN PDM_ODM_T pDM_Odm + ); + +HAL_STATUS +ODM_ConfigFWWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_FW_Config_Type ConfigType, + OUT u1Byte *pFirmware, + OUT u4Byte *pSize + ); + +u4Byte +ODM_GetHWImgVersion( + IN PDM_ODM_T pDM_Odm + ); + +s4Byte +odm_SignalScaleMapping( + IN OUT PDM_ODM_T pDM_Odm, + IN s4Byte CurrSig + ); + +#endif + +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_NoiseMonitor.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_NoiseMonitor.c new file mode 100755 index 000000000000..f8c207b09907 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_NoiseMonitor.c @@ -0,0 +1,197 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +//#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +//================================================= +// This function is for inband noise test utility only +// To obtain the inband noise level(dbm), do the following. +// 1. disable DIG and Power Saving +// 2. Set initial gain = 0x1a +// 3. Stop updating idle time pwer report (for driver read) +// - 0x80c[25] +// +//================================================= + +#define Valid_Min -35 +#define Valid_Max 10 +#define ValidCnt 5 + +s2Byte odm_InbandNoise_Monitor_NSeries(PDM_ODM_T pDM_Odm,u8 bPauseDIG,u8 IGIValue,u32 max_time) +{ + u4Byte tmp4b; + u1Byte max_rf_path=0,rf_path; + u1Byte reg_c50, reg_c58,valid_done=0; + struct noise_level noise_data; + u32 start = 0, func_start=0, func_end = 0; + + func_start = ODM_GetCurrentTime(pDM_Odm); + pDM_Odm->noise_level.noise_all = 0; + + if((pDM_Odm->RFType == ODM_1T2R) ||(pDM_Odm->RFType == ODM_2T2R)) + max_rf_path = 2; + else + max_rf_path = 1; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("odm_DebugControlInbandNoise_Nseries() ==> \n")); + + ODM_Memory_Set(pDM_Odm,&noise_data,0,sizeof(struct noise_level)); + + // + // Step 1. Disable DIG && Set initial gain. + // + + if(bPauseDIG) + { + odm_PauseDIG(pDM_Odm,ODM_PAUSE_DIG,IGIValue); + } + // + // Step 2. Disable all power save for read registers + // + //dcmd_DebugControlPowerSave(pAdapter, PSDisable); + + // + // Step 3. Get noise power level + // + start = ODM_GetCurrentTime(pDM_Odm); + while(1) + { + + //Stop updating idle time pwer report (for driver read) + ODM_SetBBReg(pDM_Odm, rFPGA0_TxGainStage, BIT25, 1); + + //Read Noise Floor Report + tmp4b = ODM_GetBBReg(pDM_Odm, 0x8f8,bMaskDWord ); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b)); + + //ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0, TestInitialGain); + //if(max_rf_path == 2) + // ODM_SetBBReg(pDM_Odm, rOFDM0_XBAGCCore1, bMaskByte0, TestInitialGain); + + //update idle time pwer report per 5us + ODM_SetBBReg(pDM_Odm, rFPGA0_TxGainStage, BIT25, 0); + + noise_data.value[ODM_RF_PATH_A] = (u1Byte)(tmp4b&0xff); + noise_data.value[ODM_RF_PATH_B] = (u1Byte)((tmp4b&0xff00)>>8); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("value_a = 0x%x(%d), value_b = 0x%x(%d)\n", + noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_B], noise_data.value[ODM_RF_PATH_B])); + + for(rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) + { + noise_data.sval[rf_path] = (s1Byte)noise_data.value[rf_path]; + noise_data.sval[rf_path] /= 2; + } + + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("sval_a = %d, sval_b = %d\n", + noise_data.sval[ODM_RF_PATH_A], noise_data.sval[ODM_RF_PATH_B])); + //ODM_delay_ms(10); + //ODM_sleep_ms(10); + + for(rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) + { + if( (noise_data.valid_cnt[rf_path] < ValidCnt) && (noise_data.sval[rf_path] < Valid_Max && noise_data.sval[rf_path] >= Valid_Min)) + { + noise_data.valid_cnt[rf_path]++; + noise_data.sum[rf_path] += noise_data.sval[rf_path]; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("RF_Path:%d Valid sval = %d\n", rf_path,noise_data.sval[rf_path])); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("Sum of sval = %d, \n", noise_data.sum[rf_path])); + if(noise_data.valid_cnt[rf_path] == ValidCnt) + { + valid_done++; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("After divided, RF_Path:%d ,sum = %d \n", rf_path,noise_data.sum[rf_path])); + } + + } + + } + + //printk("####### valid_done:%d #############\n",valid_done); + if ((valid_done==max_rf_path) || (ODM_GetProgressingTime(pDM_Odm,start) > max_time)) + { + for(rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) + { + //printk("%s PATH_%d - sum = %d, valid_cnt = %d \n",__FUNCTION__,rf_path,noise_data.sum[rf_path], noise_data.valid_cnt[rf_path]); + if(noise_data.valid_cnt[rf_path]) + noise_data.sum[rf_path] /= noise_data.valid_cnt[rf_path]; + else + noise_data.sum[rf_path] = 0; + } + break; + } + } + reg_c50 = (s4Byte)ODM_GetBBReg(pDM_Odm,rOFDM0_XAAGCCore1,bMaskByte0); + reg_c50 &= ~BIT7; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("0x%x = 0x%02x(%d)\n", rOFDM0_XAAGCCore1, reg_c50, reg_c50)); + pDM_Odm->noise_level.noise[ODM_RF_PATH_A] = -110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A]; + pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_A]; + + if(max_rf_path == 2){ + reg_c58 = (s4Byte)ODM_GetBBReg(pDM_Odm,rOFDM0_XBAGCCore1,bMaskByte0); + reg_c58 &= ~BIT7; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("0x%x = 0x%02x(%d)\n", rOFDM0_XBAGCCore1, reg_c58, reg_c58)); + pDM_Odm->noise_level.noise[ODM_RF_PATH_B] = -110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B]; + pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_B]; + } + pDM_Odm->noise_level.noise_all /= max_rf_path; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("noise_a = %d, noise_b = %d\n", + pDM_Odm->noise_level.noise[ODM_RF_PATH_A], + pDM_Odm->noise_level.noise[ODM_RF_PATH_B])); + + // + // Step 4. Recover the Dig + // + if(bPauseDIG) + { + odm_PauseDIG(pDM_Odm,ODM_RESUME_DIG,IGIValue); + } + func_end = ODM_GetProgressingTime(pDM_Odm,func_start) ; + //printk("%s noise_a = %d, noise_b = %d noise_all:%d (%d ms)\n",__FUNCTION__, + // pDM_Odm->noise_level.noise[ODM_RF_PATH_A], + // pDM_Odm->noise_level.noise[ODM_RF_PATH_B], + // pDM_Odm->noise_level.noise_all,func_end); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("odm_DebugControlInbandNoise_Nseries() <== \n")); + return pDM_Odm->noise_level.noise_all; + +} +s2Byte ODM_InbandNoise_Monitor(PVOID pDM_VOID,u8 bPauseDIG,u8 IGIValue,u32 max_time) +{ + + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES ) + { + //odm_InbandNoise_Monitor_JaguarSeries(pDM_Odm,bPauseDIG,IGIValue,max_time); + return 0; + } + else + { + return odm_InbandNoise_Monitor_NSeries(pDM_VOID,bPauseDIG,IGIValue,max_time); + } +} + + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_NoiseMonitor.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_NoiseMonitor.h new file mode 100755 index 000000000000..6625be61633a --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_NoiseMonitor.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + *****************************************************************************/ +#ifndef __ODMNOISEMONITOR_H__ +#define __ODMNOISEMONITOR_H__ + +#define ODM_MAX_CHANNEL_NUM 38//14+24 +struct noise_level +{ + //u1Byte value_a, value_b; + u1Byte value[MAX_RF_PATH]; + //s1Byte sval_a, sval_b; + s1Byte sval[MAX_RF_PATH]; + + //s4Byte noise_a=0, noise_b=0,sum_a=0, sum_b=0; + //s4Byte noise[ODM_RF_PATH_MAX]; + s4Byte sum[MAX_RF_PATH]; + //u1Byte valid_cnt_a=0, valid_cnt_b=0, + u1Byte valid[MAX_RF_PATH]; + u1Byte valid_cnt[MAX_RF_PATH]; + +}; + + +typedef struct _ODM_NOISE_MONITOR_ +{ + s1Byte noise[MAX_RF_PATH]; + s2Byte noise_all; +}ODM_NOISE_MONITOR; + +s2Byte ODM_InbandNoise_Monitor(PVOID pDM_VOID,u8 bPauseDIG,u8 IGIValue,u32 max_time); + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PathDiv.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PathDiv.c new file mode 100755 index 000000000000..3bbea923f5af --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PathDiv.c @@ -0,0 +1,1585 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + + + +VOID +odm_PathDiversityInit( + IN PVOID pDM_VOID +) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if(pDM_Odm->mp_mode == TRUE) + return; + + if(!(pDM_Odm->SupportAbility & ODM_BB_PATH_DIV)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PATH_DIV,ODM_DBG_LOUD,("Return: Not Support PathDiv\n")); + return; + } + + #if RTL8812A_SUPPORT + if(pDM_Odm->SupportICType & ODM_RTL8812) + ODM_PathDiversityInit_8812A(pDM_Odm); + #endif +#endif +} + +VOID +odm_PathDiversity( + IN PVOID pDM_VOID +) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(!(pDM_Odm->SupportAbility & ODM_BB_PATH_DIV)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PATH_DIV,ODM_DBG_LOUD,("Return: Not Support PathDiv\n")); + return; + } + +#if RTL8812A_SUPPORT + + if(pDM_Odm->SupportICType & ODM_RTL8812) + ODM_PathDiversity_8812A(pDM_Odm); +#endif +#endif //(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +} + + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +// +// 2011/12/02 MH Copy from MP oursrc for temporarily test. +// + +BOOLEAN +odm_IsConnected_92C( + IN PADAPTER Adapter +) +{ + PRT_WLAN_STA pEntry; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + u4Byte i; + BOOLEAN bConnected=FALSE; + + if(pMgntInfo->mAssoc) + { + bConnected = TRUE; + } + else + { + for(i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) + { + if(IsAPModeExist(Adapter) && GetFirstExtAdapter(Adapter) != NULL) + pEntry = AsocEntry_EnumStation(GetFirstExtAdapter(Adapter), i); + else + pEntry = AsocEntry_EnumStation(GetDefaultAdapter(Adapter), i); + + if(pEntry!=NULL) + { + if(pEntry->bAssociated) + { + bConnected = TRUE; + break; + } + } + else + { + break; + } + } + } + return bConnected; +} + +BOOLEAN +ODM_PathDiversityBeforeLink92C( + //IN PADAPTER Adapter + IN PDM_ODM_T pDM_Odm + ) +{ +#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE* pHalData = NULL; + PMGNT_INFO pMgntInfo = NULL; + //pSWAT_T pDM_SWAT_Table = &Adapter->DM_SWAT_Table; + pPD_T pDM_PDTable = NULL; + + s1Byte Score = 0; + PRT_WLAN_BSS pTmpBssDesc; + PRT_WLAN_BSS pTestBssDesc; + + u1Byte target_chnl = 0; + u2Byte index; + + if (pDM_Odm->Adapter == NULL) //For BSOD when plug/unplug fast. //By YJ,120413 + { // The ODM structure is not initialized. + return FALSE; + } + pHalData = GET_HAL_DATA(Adapter); + pMgntInfo = &Adapter->MgntInfo; + pDM_PDTable = &Adapter->DM_PDTable; + + // Condition that does not need to use path diversity. + if((!(pHalData->CVID_Version==VERSION_1_BEFORE_8703B && IS_92C_SERIAL(pHalData->VersionID))) || (pHalData->PathDivCfg!=1) || pMgntInfo->AntennaTest ) + { + RT_TRACE(COMP_INIT, DBG_LOUD, + ("ODM_PathDiversityBeforeLink92C(): No PathDiv Mechanism before link.\n")); + return FALSE; + } + + // Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF. + PlatformAcquireSpinLock(Adapter, RT_RF_STATE_SPINLOCK); + if(pHalData->eRFPowerState!=eRfOn || pMgntInfo->RFChangeInProgress || pMgntInfo->bMediaConnect) + { + PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK); + + RT_TRACE(COMP_INIT, DBG_LOUD, + ("ODM_PathDiversityBeforeLink92C(): RFChangeInProgress(%x), eRFPowerState(%x)\n", + pMgntInfo->RFChangeInProgress, + pHalData->eRFPowerState)); + + //pDM_SWAT_Table->SWAS_NoLink_State = 0; + pDM_PDTable->PathDiv_NoLink_State = 0; + + return FALSE; + } + else + { + PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK); + } + + //1 Run AntDiv mechanism "Before Link" part. + //if(pDM_SWAT_Table->SWAS_NoLink_State == 0) + if(pDM_PDTable->PathDiv_NoLink_State == 0) + { + //1 Prepare to do Scan again to check current antenna state. + + // Set check state to next step. + //pDM_SWAT_Table->SWAS_NoLink_State = 1; + pDM_PDTable->PathDiv_NoLink_State = 1; + + // Copy Current Scan list. + Adapter->MgntInfo.tmpNumBssDesc = pMgntInfo->NumBssDesc; + PlatformMoveMemory((PVOID)Adapter->MgntInfo.tmpbssDesc, (PVOID)pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC); + + // Switch Antenna to another one. + if(pDM_PDTable->DefaultRespPath == 0) + { + PHY_SetBBReg(Adapter, rCCK0_AFESetting , 0x0F000000, 0x05); // TRX path = PathB + odm_SetRespPath_92C(Adapter, 1); + pDM_PDTable->OFDMTXPath = 0xFFFFFFFF; + pDM_PDTable->CCKTXPath = 0xFFFFFFFF; + } + else + { + PHY_SetBBReg(Adapter, rCCK0_AFESetting , 0x0F000000, 0x00); // TRX path = PathA + odm_SetRespPath_92C(Adapter, 0); + pDM_PDTable->OFDMTXPath = 0x0; + pDM_PDTable->CCKTXPath = 0x0; + } +#if 0 + + pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna; + pDM_SWAT_Table->CurAntenna = (pDM_SWAT_Table->CurAntenna==Antenna_A)?Antenna_B:Antenna_A; + + RT_TRACE(COMP_INIT, DBG_LOUD, + ("ODM_SwAntDivCheckBeforeLink: Change to Ant(%s) for testing.\n", (pDM_SWAT_Table->CurAntenna==Antenna_A)?"A":"B")); + //PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, DM_SWAT_Table.CurAntenna); + pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 = ((pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 & 0xfffffcff) | (pDM_SWAT_Table->CurAntenna<<8)); + PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, pDM_SWAT_Table->SWAS_NoLink_BK_Reg860); +#endif + + // Go back to scan function again. + RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C: Scan one more time\n")); + pMgntInfo->ScanStep=0; + target_chnl = odm_SwAntDivSelectScanChnl(Adapter); + odm_SwAntDivConstructScanChnl(Adapter, target_chnl); + PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5); + + return TRUE; + } + else + { + //1 ScanComple() is called after antenna swiched. + //1 Check scan result and determine which antenna is going + //1 to be used. + + for(index=0; indexMgntInfo.tmpNumBssDesc; index++) + { + pTmpBssDesc = &(Adapter->MgntInfo.tmpbssDesc[index]); + pTestBssDesc = &(pMgntInfo->bssDesc[index]); + + if(PlatformCompareMemory(pTestBssDesc->bdBssIdBuf, pTmpBssDesc->bdBssIdBuf, 6)!=0) + { + RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C(): ERROR!! This shall not happen.\n")); + continue; + } + + if(pTmpBssDesc->RecvSignalPower > pTestBssDesc->RecvSignalPower) + { + RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C: Compare scan entry: Score++\n")); + RT_PRINT_STR(COMP_INIT, DBG_LOUD, "SSID: ", pTestBssDesc->bdSsIdBuf, pTestBssDesc->bdSsIdLen); + RT_TRACE(COMP_INIT, DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + + Score++; + PlatformMoveMemory(pTestBssDesc, pTmpBssDesc, sizeof(RT_WLAN_BSS)); + } + else if(pTmpBssDesc->RecvSignalPower < pTestBssDesc->RecvSignalPower) + { + RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C: Compare scan entry: Score--\n")); + RT_PRINT_STR(COMP_INIT, DBG_LOUD, "SSID: ", pTestBssDesc->bdSsIdBuf, pTestBssDesc->bdSsIdLen); + RT_TRACE(COMP_INIT, DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower)); + Score--; + } + + } + + if(pMgntInfo->NumBssDesc!=0 && Score<=0) + { + RT_TRACE(COMP_INIT, DBG_LOUD, + ("ODM_PathDiversityBeforeLink92C(): DefaultRespPath=%d\n", pDM_PDTable->DefaultRespPath)); + + //pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna; + } + else + { + RT_TRACE(COMP_INIT, DBG_LOUD, + ("ODM_PathDiversityBeforeLink92C(): DefaultRespPath=%d\n", pDM_PDTable->DefaultRespPath)); + + if(pDM_PDTable->DefaultRespPath == 0) + { + pDM_PDTable->OFDMTXPath = 0xFFFFFFFF; + pDM_PDTable->CCKTXPath = 0xFFFFFFFF; + odm_SetRespPath_92C(Adapter, 1); + } + else + { + pDM_PDTable->OFDMTXPath = 0x0; + pDM_PDTable->CCKTXPath = 0x0; + odm_SetRespPath_92C(Adapter, 0); + } + PHY_SetBBReg(Adapter, rCCK0_AFESetting , 0x0F000000, 0x01); // RX path = PathAB + + //pDM_SWAT_Table->CurAntenna = pDM_SWAT_Table->PreAntenna; + + //PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, DM_SWAT_Table.CurAntenna); + //pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 = ((pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 & 0xfffffcff) | (pDM_SWAT_Table->CurAntenna<<8)); + //PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, pDM_SWAT_Table->SWAS_NoLink_BK_Reg860); + } + + // Check state reset to default and wait for next time. + //pDM_SWAT_Table->SWAS_NoLink_State = 0; + pDM_PDTable->PathDiv_NoLink_State = 0; + + return FALSE; + } +#else + return FALSE; +#endif + +} + + + +VOID +odm_PathDiversityAfterLink_92C( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + pPD_T pDM_PDTable = &Adapter->DM_PDTable; + u1Byte DefaultRespPath=0; + + if((!(pHalData->CVID_Version==VERSION_1_BEFORE_8703B && IS_92C_SERIAL(pHalData->VersionID))) || (pHalData->PathDivCfg != 1) || (pHalData->eRFPowerState == eRfOff)) + { + if(pHalData->PathDivCfg == 0) + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("No ODM_TXPathDiversity()\n")); + } + else + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("2T ODM_TXPathDiversity()\n")); + } + return; + } + if(!odm_IsConnected_92C(Adapter)) + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("ODM_TXPathDiversity(): No Connections\n")); + return; + } + + + if(pDM_PDTable->TrainingState == 0) + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("ODM_TXPathDiversity() ==>\n")); + odm_OFDMTXPathDiversity_92C(Adapter); + + if((pDM_PDTable->CCKPathDivEnable == TRUE) && (pDM_PDTable->OFDM_Pkt_Cnt < 100)) + { + //RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: TrainingState=0\n")); + + if(pDM_PDTable->CCK_Pkt_Cnt > 300) + pDM_PDTable->Timer = 20; + else if(pDM_PDTable->CCK_Pkt_Cnt > 100) + pDM_PDTable->Timer = 60; + else + pDM_PDTable->Timer = 250; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: timer=%d\n",pDM_PDTable->Timer)); + + PHY_SetBBReg(Adapter, rCCK0_AFESetting , 0x0F000000, 0x00); // RX path = PathA + pDM_PDTable->TrainingState = 1; + pHalData->RSSI_test = TRUE; + ODM_SetTimer( pDM_Odm, &pDM_Odm->CCKPathDiversityTimer, pDM_PDTable->Timer); //ms + } + else + { + pDM_PDTable->CCKTXPath = pDM_PDTable->OFDMTXPath; + DefaultRespPath = pDM_PDTable->OFDMDefaultRespPath; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_SetRespPath_92C: Skip odm_CCKTXPathDiversity_92C, DefaultRespPath is OFDM\n")); + odm_SetRespPath_92C(Adapter, DefaultRespPath); + odm_ResetPathDiversity_92C(Adapter); + RT_TRACE( COMP_INIT, DBG_LOUD, ("ODM_TXPathDiversity() <==\n")); + } + } + else if(pDM_PDTable->TrainingState == 1) + { + //RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: TrainingState=1\n")); + PHY_SetBBReg(Adapter, rCCK0_AFESetting , 0x0F000000, 0x05); // RX path = PathB + pDM_PDTable->TrainingState = 2; + ODM_SetTimer( pDM_Odm, &pDM_Odm->CCKPathDiversityTimer, pDM_PDTable->Timer); //ms + } + else + { + //RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: TrainingState=2\n")); + pDM_PDTable->TrainingState = 0; + odm_CCKTXPathDiversity_92C(Adapter); + if(pDM_PDTable->OFDM_Pkt_Cnt != 0) + { + DefaultRespPath = pDM_PDTable->OFDMDefaultRespPath; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_SetRespPath_92C: DefaultRespPath is OFDM\n")); + } + else + { + DefaultRespPath = pDM_PDTable->CCKDefaultRespPath; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_SetRespPath_92C: DefaultRespPath is CCK\n")); + } + odm_SetRespPath_92C(Adapter, DefaultRespPath); + odm_ResetPathDiversity_92C(Adapter); + RT_TRACE( COMP_INIT, DBG_LOUD, ("ODM_TXPathDiversity() <==\n")); + } + +} + +VOID +odm_SetRespPath_92C( + IN PADAPTER Adapter, + IN u1Byte DefaultRespPath + ) +{ + pPD_T pDM_PDTable = &Adapter->DM_PDTable; + + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_SetRespPath_92C: Select Response Path=%d\n",DefaultRespPath)); + if(DefaultRespPath != pDM_PDTable->DefaultRespPath) + { + if(DefaultRespPath == 0) + { + PlatformEFIOWrite1Byte(Adapter, 0x6D8, (PlatformEFIORead1Byte(Adapter, 0x6D8)&0xc0)|0x15); + } + else + { + PlatformEFIOWrite1Byte(Adapter, 0x6D8, (PlatformEFIORead1Byte(Adapter, 0x6D8)&0xc0)|0x2A); + } + } + pDM_PDTable->DefaultRespPath = DefaultRespPath; +} + +VOID +odm_OFDMTXPathDiversity_92C( + IN PADAPTER Adapter) +{ +// HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + PRT_WLAN_STA pEntry; + u1Byte i, DefaultRespPath = 0; + s4Byte MinRSSI = 0xFF; + pPD_T pDM_PDTable = &Adapter->DM_PDTable; + pDM_PDTable->OFDMTXPath = 0; + + //1 Default Port + if(pMgntInfo->mAssoc) + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_OFDMTXPathDiversity_92C: Default port RSSI[0]=%d, RSSI[1]=%d\n", + Adapter->RxStats.RxRSSIPercentage[0], Adapter->RxStats.RxRSSIPercentage[1])); + if(Adapter->RxStats.RxRSSIPercentage[0] > Adapter->RxStats.RxRSSIPercentage[1]) + { + pDM_PDTable->OFDMTXPath = pDM_PDTable->OFDMTXPath & (~BIT0); + MinRSSI = Adapter->RxStats.RxRSSIPercentage[1]; + DefaultRespPath = 0; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_OFDMTXPathDiversity_92C: Default port Select Path-0\n")); + } + else + { + pDM_PDTable->OFDMTXPath = pDM_PDTable->OFDMTXPath | BIT0; + MinRSSI = Adapter->RxStats.RxRSSIPercentage[0]; + DefaultRespPath = 1; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_OFDMTXPathDiversity_92C: Default port Select Path-1\n")); + } + //RT_TRACE( COMP_INIT, DBG_LOUD, ("pDM_PDTable->OFDMTXPath =0x%x\n",pDM_PDTable->OFDMTXPath)); + } + //1 Extension Port + for(i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) + { + if(IsAPModeExist(Adapter) && GetFirstExtAdapter(Adapter) != NULL) + pEntry = AsocEntry_EnumStation(GetFirstExtAdapter(Adapter), i); + else + pEntry = AsocEntry_EnumStation(GetDefaultAdapter(Adapter), i); + + if(pEntry!=NULL) + { + if(pEntry->bAssociated) + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_OFDMTXPathDiversity_92C: MACID=%d, RSSI_0=%d, RSSI_1=%d\n", + pEntry->AssociatedMacId, pEntry->rssi_stat.RxRSSIPercentage[0], pEntry->rssi_stat.RxRSSIPercentage[1])); + + if(pEntry->rssi_stat.RxRSSIPercentage[0] > pEntry->rssi_stat.RxRSSIPercentage[1]) + { + pDM_PDTable->OFDMTXPath = pDM_PDTable->OFDMTXPath & ~(BIT(pEntry->AssociatedMacId)); + //pHalData->TXPath = pHalData->TXPath & ~(1<<(pEntry->AssociatedMacId)); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_OFDMTXPathDiversity_92C: MACID=%d Select Path-0\n", pEntry->AssociatedMacId)); + if(pEntry->rssi_stat.RxRSSIPercentage[1] < MinRSSI) + { + MinRSSI = pEntry->rssi_stat.RxRSSIPercentage[1]; + DefaultRespPath = 0; + } + } + else + { + pDM_PDTable->OFDMTXPath = pDM_PDTable->OFDMTXPath | BIT(pEntry->AssociatedMacId); + //pHalData->TXPath = pHalData->TXPath | (1 << (pEntry->AssociatedMacId)); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_OFDMTXPathDiversity_92C: MACID=%d Select Path-1\n", pEntry->AssociatedMacId)); + if(pEntry->rssi_stat.RxRSSIPercentage[0] < MinRSSI) + { + MinRSSI = pEntry->rssi_stat.RxRSSIPercentage[0]; + DefaultRespPath = 1; + } + } + } + } + else + { + break; + } + } + + pDM_PDTable->OFDMDefaultRespPath = DefaultRespPath; +} + + +VOID +odm_CCKTXPathDiversity_92C( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + PRT_WLAN_STA pEntry; + s4Byte MinRSSI = 0xFF; + u1Byte i, DefaultRespPath = 0; +// BOOLEAN bBModePathDiv = FALSE; + pPD_T pDM_PDTable = &Adapter->DM_PDTable; + + //1 Default Port + if(pMgntInfo->mAssoc) + { + if(pHalData->OFDM_Pkt_Cnt == 0) + { + for(i=0; i<2; i++) + { + if(pDM_PDTable->RSSI_CCK_Path_cnt[i] > 1) //Because the first packet is discarded + pDM_PDTable->RSSI_CCK_Path[i] = pDM_PDTable->RSSI_CCK_Path[i] / (pDM_PDTable->RSSI_CCK_Path_cnt[i]-1); + else + pDM_PDTable->RSSI_CCK_Path[i] = 0; + } + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: pDM_PDTable->RSSI_CCK_Path[0]=%d, pDM_PDTable->RSSI_CCK_Path[1]=%d\n", + pDM_PDTable->RSSI_CCK_Path[0], pDM_PDTable->RSSI_CCK_Path[1])); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: pDM_PDTable->RSSI_CCK_Path_cnt[0]=%d, pDM_PDTable->RSSI_CCK_Path_cnt[1]=%d\n", + pDM_PDTable->RSSI_CCK_Path_cnt[0], pDM_PDTable->RSSI_CCK_Path_cnt[1])); + + if(pDM_PDTable->RSSI_CCK_Path[0] > pDM_PDTable->RSSI_CCK_Path[1]) + { + pDM_PDTable->CCKTXPath = pDM_PDTable->CCKTXPath & (~BIT0); + MinRSSI = pDM_PDTable->RSSI_CCK_Path[1]; + DefaultRespPath = 0; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: Default port Select CCK Path-0\n")); + } + else if(pDM_PDTable->RSSI_CCK_Path[0] < pDM_PDTable->RSSI_CCK_Path[1]) + { + pDM_PDTable->CCKTXPath = pDM_PDTable->CCKTXPath | BIT0; + MinRSSI = pDM_PDTable->RSSI_CCK_Path[0]; + DefaultRespPath = 1; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: Default port Select CCK Path-1\n")); + } + else + { + if((pDM_PDTable->RSSI_CCK_Path[0] != 0) && (pDM_PDTable->RSSI_CCK_Path[0] < MinRSSI)) + { + pDM_PDTable->CCKTXPath = pDM_PDTable->CCKTXPath & (~BIT0); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: Default port Select CCK Path-0\n")); + MinRSSI = pDM_PDTable->RSSI_CCK_Path[1]; + DefaultRespPath = 0; + } + else + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: Default port unchange CCK Path\n")); + } + } + } + else //Follow OFDM decision + { + pDM_PDTable->CCKTXPath = (pDM_PDTable->CCKTXPath & (~BIT0)) | (pDM_PDTable->OFDMTXPath &BIT0); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: Follow OFDM decision, Default port Select CCK Path-%d\n", + pDM_PDTable->CCKTXPath &BIT0)); + } + } + //1 Extension Port + for(i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) + { + if(IsAPModeExist(Adapter) && GetFirstExtAdapter(Adapter) != NULL) + pEntry = AsocEntry_EnumStation(GetFirstExtAdapter(Adapter), i); + else + pEntry = AsocEntry_EnumStation(GetDefaultAdapter(Adapter), i); + + if(pEntry!=NULL) + { + if(pEntry->bAssociated) + { + if(pEntry->rssi_stat.OFDM_Pkt_Cnt == 0) + { + u1Byte j=0; + for(j=0; j<2; j++) + { + if(pEntry->rssi_stat.RSSI_CCK_Path_cnt[j] > 1) + pEntry->rssi_stat.RSSI_CCK_Path[j] = pEntry->rssi_stat.RSSI_CCK_Path[j] / (pEntry->rssi_stat.RSSI_CCK_Path_cnt[j]-1); + else + pEntry->rssi_stat.RSSI_CCK_Path[j] = 0; + } + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: MACID=%d, RSSI_CCK0=%d, RSSI_CCK1=%d\n", + pEntry->AssociatedMacId, pEntry->rssi_stat.RSSI_CCK_Path[0], pEntry->rssi_stat.RSSI_CCK_Path[1])); + + if(pEntry->rssi_stat.RSSI_CCK_Path[0] >pEntry->rssi_stat.RSSI_CCK_Path[1]) + { + pDM_PDTable->CCKTXPath = pDM_PDTable->CCKTXPath & ~(BIT(pEntry->AssociatedMacId)); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: MACID=%d Select CCK Path-0\n", pEntry->AssociatedMacId)); + if(pEntry->rssi_stat.RSSI_CCK_Path[1] < MinRSSI) + { + MinRSSI = pEntry->rssi_stat.RSSI_CCK_Path[1]; + DefaultRespPath = 0; + } + } + else if(pEntry->rssi_stat.RSSI_CCK_Path[0] rssi_stat.RSSI_CCK_Path[1]) + { + pDM_PDTable->CCKTXPath = pDM_PDTable->CCKTXPath | BIT(pEntry->AssociatedMacId); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: MACID=%d Select CCK Path-1\n", pEntry->AssociatedMacId)); + if(pEntry->rssi_stat.RSSI_CCK_Path[0] < MinRSSI) + { + MinRSSI = pEntry->rssi_stat.RSSI_CCK_Path[0]; + DefaultRespPath = 1; + } + } + else + { + if((pEntry->rssi_stat.RSSI_CCK_Path[0] != 0) && (pEntry->rssi_stat.RSSI_CCK_Path[0] < MinRSSI)) + { + pDM_PDTable->CCKTXPath = pDM_PDTable->CCKTXPath & ~(BIT(pEntry->AssociatedMacId)); + MinRSSI = pEntry->rssi_stat.RSSI_CCK_Path[1]; + DefaultRespPath = 0; + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: MACID=%d Select CCK Path-0\n", pEntry->AssociatedMacId)); + } + else + { + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: MACID=%d unchange CCK Path\n", pEntry->AssociatedMacId)); + } + } + } + else //Follow OFDM decision + { + pDM_PDTable->CCKTXPath = (pDM_PDTable->CCKTXPath & (~(BIT(pEntry->AssociatedMacId)))) | (pDM_PDTable->OFDMTXPath & BIT(pEntry->AssociatedMacId)); + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C: Follow OFDM decision, MACID=%d Select CCK Path-%d\n", + pEntry->AssociatedMacId, (pDM_PDTable->CCKTXPath & BIT(pEntry->AssociatedMacId))>>(pEntry->AssociatedMacId))); + } + } + } + else + { + break; + } + } + + RT_TRACE( COMP_INIT, DBG_LOUD, ("odm_CCKTXPathDiversity_92C:MinRSSI=%d\n",MinRSSI)); + + if(MinRSSI == 0xFF) + DefaultRespPath = pDM_PDTable->CCKDefaultRespPath; + + pDM_PDTable->CCKDefaultRespPath = DefaultRespPath; +} + + +VOID +odm_ResetPathDiversity_92C( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + pPD_T pDM_PDTable = &Adapter->DM_PDTable; + PRT_WLAN_STA pEntry; + u4Byte i,j; + + pHalData->RSSI_test = FALSE; + pDM_PDTable->CCK_Pkt_Cnt = 0; + pDM_PDTable->OFDM_Pkt_Cnt = 0; + pHalData->CCK_Pkt_Cnt =0; + pHalData->OFDM_Pkt_Cnt =0; + + if(pDM_PDTable->CCKPathDivEnable == TRUE) + PHY_SetBBReg(Adapter, rCCK0_AFESetting , 0x0F000000, 0x01); //RX path = PathAB + + for(i=0; i<2; i++) + { + pDM_PDTable->RSSI_CCK_Path_cnt[i]=0; + pDM_PDTable->RSSI_CCK_Path[i] = 0; + } + for(i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) + { + if(IsAPModeExist(Adapter) && GetFirstExtAdapter(Adapter) != NULL) + pEntry = AsocEntry_EnumStation(GetFirstExtAdapter(Adapter), i); + else + pEntry = AsocEntry_EnumStation(GetDefaultAdapter(Adapter), i); + + if(pEntry!=NULL) + { + pEntry->rssi_stat.CCK_Pkt_Cnt = 0; + pEntry->rssi_stat.OFDM_Pkt_Cnt = 0; + for(j=0; j<2; j++) + { + pEntry->rssi_stat.RSSI_CCK_Path_cnt[j] = 0; + pEntry->rssi_stat.RSSI_CCK_Path[j] = 0; + } + } + else + break; + } +} + + + + + +VOID +odm_CCKTXPathDiversityCallback( + PRT_TIMER pTimer +) +{ +#if USE_WORKITEM + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; +#endif + +#if DEV_BUS_TYPE==RT_PCI_INTERFACE +#if USE_WORKITEM + PlatformScheduleWorkItem(&pDM_Odm->CCKPathDiversityWorkitem); +#else + odm_PathDiversityAfterLink_92C(Adapter); +#endif +#else + PlatformScheduleWorkItem(&pDM_Odm->CCKPathDiversityWorkitem); +#endif + +} + + +VOID +odm_CCKTXPathDiversityWorkItemCallback( + IN PVOID pContext + ) +{ + PADAPTER Adapter = (PADAPTER)pContext; + + odm_CCKTXPathDiversity_92C(Adapter); +} + +// +// 20100514 Luke/Joseph: +// Callback function for 500ms antenna test trying. +// +VOID +odm_PathDivChkAntSwitchCallback( + PRT_TIMER pTimer +) +{ + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + +#if USE_WORKITEM + PlatformScheduleWorkItem(&pDM_Odm->PathDivSwitchWorkitem); +#else + odm_PathDivChkAntSwitch(pDM_Odm); +#endif +#else + PlatformScheduleWorkItem(&pDM_Odm->PathDivSwitchWorkitem); +#endif + +//odm_SwAntDivChkAntSwitch(Adapter, SWAW_STEP_DETERMINE); + +} + + +VOID +odm_PathDivChkAntSwitchWorkitemCallback( + IN PVOID pContext + ) +{ + PADAPTER pAdapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + odm_PathDivChkAntSwitch(pDM_Odm); +} + + + //MAC0_ACCESS_PHY1 + +// 2011-06-22 Neil Chen & Gary Hsin +// Refer to Jr.Luke's SW ANT DIV +// 92D Path Diversity Main function +// refer to 88C software antenna diversity +// +VOID +odm_PathDivChkAntSwitch( + PDM_ODM_T pDM_Odm + //PADAPTER Adapter, + //u1Byte Step +) +{ + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + s4Byte curRSSI=100, RSSI_A, RSSI_B; + u1Byte nextAntenna=AUX_ANT; + static u8Byte lastTxOkCnt=0, lastRxOkCnt=0; + u8Byte curTxOkCnt, curRxOkCnt; + static u8Byte TXByteCnt_A=0, TXByteCnt_B=0, RXByteCnt_A=0, RXByteCnt_B=0; + u8Byte CurByteCnt=0, PreByteCnt=0; + static u1Byte TrafficLoad = TRAFFIC_LOW; + u1Byte Score_A=0, Score_B=0; + u1Byte i=0x0; + // Neil Chen + static u1Byte pathdiv_para=0x0; + static u1Byte switchfirsttime=0x00; + // u1Byte regB33 = (u1Byte) PHY_QueryBBReg(Adapter, 0xB30,BIT27); + u1Byte regB33 = (u1Byte)ODM_GetBBReg(pDM_Odm, PATHDIV_REG, BIT27); + + + //u1Byte reg637 =0x0; + static u1Byte fw_value=0x0; + //u8Byte curTxOkCnt_tmp, curRxOkCnt_tmp; + PADAPTER BuddyAdapter = Adapter->BuddyAdapter; // another adapter MAC + // Path Diversity //Neil Chen--2011--06--22 + + //u1Byte PathDiv_Trigger = (u1Byte) PHY_QueryBBReg(Adapter, 0xBA0,BIT31); + u1Byte PathDiv_Trigger = (u1Byte) ODM_GetBBReg(pDM_Odm, PATHDIV_TRI,BIT31); + u1Byte PathDiv_Enable = pHalData->bPathDiv_Enable; + + + //DbgPrint("Path Div PG Value:%x \n",PathDiv_Enable); + if((BuddyAdapter==NULL)||(!PathDiv_Enable)||(PathDiv_Trigger)||(pHalData->CurrentBandType == BAND_ON_2_4G)) + { + return; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD,("===================>odm_PathDivChkAntSwitch()\n")); + + // The first time to switch path excluding 2nd, 3rd, ....etc.... + if(switchfirsttime==0) + { + if(regB33==0) + { + pDM_SWAT_Table->CurAntenna = MAIN_ANT; // Default MAC0_5G-->Path A (current antenna) + } + } + + // Condition that does not need to use antenna diversity. + if(pDM_Odm->SupportICType != ODM_RTL8192D) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("odm_PathDiversityMechanims(): No PathDiv Mechanism.\n")); + return; + } + + // Radio off: Status reset to default and return. + if(pHalData->eRFPowerState==eRfOff) + { + //ODM_SwAntDivRestAfterLink(Adapter); + return; + } + + /* + // Handling step mismatch condition. + // Peak step is not finished at last time. Recover the variable and check again. + if( Step != pDM_SWAT_Table->try_flag ) + { + ODM_SwAntDivRestAfterLink(Adapter); + } */ + + if(pDM_SWAT_Table->try_flag == 0xff) + { + // Select RSSI checking target + if(pMgntInfo->mAssoc && !ACTING_AS_AP(Adapter)) + { + // Target: Infrastructure mode AP. + pHalData->RSSI_target = NULL; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("odm_PathDivMechanism(): RSSI_target is DEF AP!\n")); + } + else + { + u1Byte index = 0; + PRT_WLAN_STA pEntry = NULL; + PADAPTER pTargetAdapter = NULL; + + if( pMgntInfo->mIbss || ACTING_AS_AP(Adapter) ) + { + // Target: AP/IBSS peer. + pTargetAdapter = Adapter; + } + else if(IsAPModeExist(Adapter) && GetFirstExtAdapter(Adapter) != NULL) + { + // Target: VWIFI peer. + pTargetAdapter = GetFirstExtAdapter(Adapter); + } + + if(pTargetAdapter != NULL) + { + for(index=0; indexbAssociated) + break; + } + } + } + + if(pEntry == NULL) + { + ODM_PathDivRestAfterLink(pDM_Odm); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("odm_SwAntDivChkAntSwitch(): No Link.\n")); + return; + } + else + { + pHalData->RSSI_target = pEntry; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("odm_SwAntDivChkAntSwitch(): RSSI_target is PEER STA\n")); + } + } + + pHalData->RSSI_cnt_A = 0; + pHalData->RSSI_cnt_B = 0; + pDM_SWAT_Table->try_flag = 0; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("odm_SwAntDivChkAntSwitch(): Set try_flag to 0 prepare for peak!\n")); + return; + } + else + { + // 1st step + curTxOkCnt = Adapter->TxStats.NumTxBytesUnicast - lastTxOkCnt; + curRxOkCnt = Adapter->RxStats.NumRxBytesUnicast - lastRxOkCnt; + lastTxOkCnt = Adapter->TxStats.NumTxBytesUnicast; + lastRxOkCnt = Adapter->RxStats.NumRxBytesUnicast; + + if(pDM_SWAT_Table->try_flag == 1) // Training State + { + if(pDM_SWAT_Table->CurAntenna == MAIN_ANT) + { + TXByteCnt_A += curTxOkCnt; + RXByteCnt_A += curRxOkCnt; + } + else + { + TXByteCnt_B += curTxOkCnt; + RXByteCnt_B += curRxOkCnt; + } + + nextAntenna = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)? AUX_ANT : MAIN_ANT; + pDM_SWAT_Table->RSSI_Trying--; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH DIV=: RSSI_Trying = %d\n",pDM_SWAT_Table->RSSI_Trying)); + if(pDM_SWAT_Table->RSSI_Trying == 0) + { + CurByteCnt = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)? (TXByteCnt_A+RXByteCnt_A) : (TXByteCnt_B+RXByteCnt_B); + PreByteCnt = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)? (TXByteCnt_B+RXByteCnt_B) : (TXByteCnt_A+RXByteCnt_A); + + if(TrafficLoad == TRAFFIC_HIGH) + { + //CurByteCnt = PlatformDivision64(CurByteCnt, 9); + PreByteCnt =PreByteCnt*9; + } + else if(TrafficLoad == TRAFFIC_LOW) + { + //CurByteCnt = PlatformDivision64(CurByteCnt, 2); + PreByteCnt =PreByteCnt*2; + } + if(pHalData->RSSI_cnt_A > 0) + RSSI_A = pHalData->RSSI_sum_A/pHalData->RSSI_cnt_A; + else + RSSI_A = 0; + if(pHalData->RSSI_cnt_B > 0) + RSSI_B = pHalData->RSSI_sum_B/pHalData->RSSI_cnt_B; + else + RSSI_B = 0; + curRSSI = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)? RSSI_A : RSSI_B; + pDM_SWAT_Table->PreRSSI = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)? RSSI_B : RSSI_A; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH DIV=: PreRSSI = %d, CurRSSI = %d\n",pDM_SWAT_Table->PreRSSI, curRSSI)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH DIV=: preAntenna= %s, curAntenna= %s \n", + (pDM_SWAT_Table->PreAntenna == MAIN_ANT?"MAIN":"AUX"), (pDM_SWAT_Table->CurAntenna == MAIN_ANT?"MAIN":"AUX"))); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH DIV=: RSSI_A= %d, RSSI_cnt_A = %d, RSSI_B= %d, RSSI_cnt_B = %d\n", + RSSI_A, pHalData->RSSI_cnt_A, RSSI_B, pHalData->RSSI_cnt_B)); + } + + } + else // try_flag=0 + { + + if(pHalData->RSSI_cnt_A > 0) + RSSI_A = pHalData->RSSI_sum_A/pHalData->RSSI_cnt_A; + else + RSSI_A = 0; + if(pHalData->RSSI_cnt_B > 0) + RSSI_B = pHalData->RSSI_sum_B/pHalData->RSSI_cnt_B; + else + RSSI_B = 0; + curRSSI = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)? RSSI_A : RSSI_B; + pDM_SWAT_Table->PreRSSI = (pDM_SWAT_Table->PreAntenna == MAIN_ANT)? RSSI_A : RSSI_B; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH DIV=: PreRSSI = %d, CurRSSI = %d\n", pDM_SWAT_Table->PreRSSI, curRSSI)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH DIV=: preAntenna= %s, curAntenna= %s \n", + (pDM_SWAT_Table->PreAntenna == MAIN_ANT?"MAIN":"AUX"), (pDM_SWAT_Table->CurAntenna == MAIN_ANT?"MAIN":"AUX"))); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH DIV=: RSSI_A= %d, RSSI_cnt_A = %d, RSSI_B= %d, RSSI_cnt_B = %d\n", + RSSI_A, pHalData->RSSI_cnt_A, RSSI_B, pHalData->RSSI_cnt_B)); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Ekul:curTxOkCnt = %d\n", curTxOkCnt)); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Ekul:curRxOkCnt = %d\n", curRxOkCnt)); + } + + //1 Trying State + if((pDM_SWAT_Table->try_flag == 1)&&(pDM_SWAT_Table->RSSI_Trying == 0)) + { + + if(pDM_SWAT_Table->TestMode == TP_MODE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: TestMode = TP_MODE")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH= TRY:CurByteCnt = %"i64fmt"d,", CurByteCnt)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH= TRY:PreByteCnt = %"i64fmt"d\n",PreByteCnt)); + if(CurByteCnt < PreByteCnt) + { + if(pDM_SWAT_Table->CurAntenna == MAIN_ANT) + pDM_SWAT_Table->SelectAntennaMap=pDM_SWAT_Table->SelectAntennaMap<<1; + else + pDM_SWAT_Table->SelectAntennaMap=(pDM_SWAT_Table->SelectAntennaMap<<1)+1; + } + else + { + if(pDM_SWAT_Table->CurAntenna == MAIN_ANT) + pDM_SWAT_Table->SelectAntennaMap=(pDM_SWAT_Table->SelectAntennaMap<<1)+1; + else + pDM_SWAT_Table->SelectAntennaMap=pDM_SWAT_Table->SelectAntennaMap<<1; + } + for (i= 0; i<8; i++) + { + if(((pDM_SWAT_Table->SelectAntennaMap>>i)&BIT0) == 1) + Score_A++; + else + Score_B++; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("SelectAntennaMap=%x\n ",pDM_SWAT_Table->SelectAntennaMap)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Score_A=%d, Score_B=%d\n", Score_A, Score_B)); + + if(pDM_SWAT_Table->CurAntenna == MAIN_ANT) + { + nextAntenna = (Score_A >= Score_B)?MAIN_ANT:AUX_ANT; + } + else + { + nextAntenna = (Score_B >= Score_A)?AUX_ANT:MAIN_ANT; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: nextAntenna=%s\n",(nextAntenna==MAIN_ANT)?"MAIN":"AUX")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: preAntenna= %s, curAntenna= %s \n", + (pDM_SWAT_Table->PreAntenna == MAIN_ANT?"MAIN":"AUX"), (pDM_SWAT_Table->CurAntenna == MAIN_ANT?"MAIN":"AUX"))); + + if(nextAntenna != pDM_SWAT_Table->CurAntenna) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Switch back to another antenna")); + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: current anntena is good\n")); + } + } + + + if(pDM_SWAT_Table->TestMode == RSSI_MODE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: TestMode = RSSI_MODE")); + pDM_SWAT_Table->SelectAntennaMap=0xAA; + if(curRSSI < pDM_SWAT_Table->PreRSSI) //Current antenna is worse than previous antenna + { + //RT_TRACE(COMP_INIT, DBG_LOUD, ("SWAS: Switch back to another antenna")); + nextAntenna = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)?AUX_ANT : MAIN_ANT; + } + else // current anntena is good + { + nextAntenna =pDM_SWAT_Table->CurAntenna; + //RT_TRACE(COMP_INIT, DBG_LOUD, ("SWAS: current anntena is good\n")); + } + } + + pDM_SWAT_Table->try_flag = 0; + pHalData->RSSI_test = FALSE; + pHalData->RSSI_sum_A = 0; + pHalData->RSSI_cnt_A = 0; + pHalData->RSSI_sum_B = 0; + pHalData->RSSI_cnt_B = 0; + TXByteCnt_A = 0; + TXByteCnt_B = 0; + RXByteCnt_A = 0; + RXByteCnt_B = 0; + + } + + //1 Normal State + else if(pDM_SWAT_Table->try_flag == 0) + { + if(TrafficLoad == TRAFFIC_HIGH) + { + if ((curTxOkCnt+curRxOkCnt) > 3750000)//if(PlatformDivision64(curTxOkCnt+curRxOkCnt, 2) > 1875000) + TrafficLoad = TRAFFIC_HIGH; + else + TrafficLoad = TRAFFIC_LOW; + } + else if(TrafficLoad == TRAFFIC_LOW) + { + if ((curTxOkCnt+curRxOkCnt) > 3750000)//if(PlatformDivision64(curTxOkCnt+curRxOkCnt, 2) > 1875000) + TrafficLoad = TRAFFIC_HIGH; + else + TrafficLoad = TRAFFIC_LOW; + } + if(TrafficLoad == TRAFFIC_HIGH) + pDM_SWAT_Table->bTriggerAntennaSwitch = 0; + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Normal:TrafficLoad = %llu\n", curTxOkCnt+curRxOkCnt)); + + //Prepare To Try Antenna + nextAntenna = (pDM_SWAT_Table->CurAntenna == MAIN_ANT)? AUX_ANT : MAIN_ANT; + pDM_SWAT_Table->try_flag = 1; + pHalData->RSSI_test = TRUE; + if((curRxOkCnt+curTxOkCnt) > 1000) + { +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + pDM_SWAT_Table->RSSI_Trying = 4; +#else + pDM_SWAT_Table->RSSI_Trying = 2; +#endif + pDM_SWAT_Table->TestMode = TP_MODE; + } + else + { + pDM_SWAT_Table->RSSI_Trying = 2; + pDM_SWAT_Table->TestMode = RSSI_MODE; + + } + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("SWAS: Normal State -> Begin Trying!\n")); + pHalData->RSSI_sum_A = 0; + pHalData->RSSI_cnt_A = 0; + pHalData->RSSI_sum_B = 0; + pHalData->RSSI_cnt_B = 0; + } // end of try_flag=0 + } + + //1 4.Change TRX antenna + if(nextAntenna != pDM_SWAT_Table->CurAntenna) + { + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Change TX Antenna!\n ")); + //PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, nextAntenna); for 88C + if(nextAntenna==MAIN_ANT) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Next Antenna is RF PATH A\n ")); + pathdiv_para = 0x02; //02 to switchback to RF path A + fw_value = 0x03; +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + odm_PathDiversity_8192D(pDM_Odm, pathdiv_para); +#else + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_PathDiv,1,(pu1Byte)(&fw_value)); +#endif + } + else if(nextAntenna==AUX_ANT) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Next Antenna is RF PATH B\n ")); + if(switchfirsttime==0) // First Time To Enter Path Diversity + { + switchfirsttime=0x01; + pathdiv_para = 0x00; + fw_value=0x00; // to backup RF Path A Releated Registers + +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + odm_PathDiversity_8192D(pDM_Odm, pathdiv_para); +#else + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_PathDiv,1,(pu1Byte)(&fw_value)); + //for(u1Byte n=0; n<80,n++) + //{ + //delay_us(500); + ODM_delay_ms(500); + odm_PathDiversity_8192D(pDM_Odm, pathdiv_para); + + fw_value=0x01; // to backup RF Path A Releated Registers + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_PathDiv,1,(pu1Byte)(&fw_value)); +#endif + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: FIRST TIME To DO PATH SWITCH!\n ")); + } + else + { + pathdiv_para = 0x01; + fw_value = 0x02; +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + odm_PathDiversity_8192D(pDM_Odm, pathdiv_para); +#else + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_PathDiv,1,(pu1Byte)(&fw_value)); +#endif + } + } + // odm_PathDiversity_8192D(Adapter, pathdiv_para); + } + + //1 5.Reset Statistics + pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna; + pDM_SWAT_Table->CurAntenna = nextAntenna; + pDM_SWAT_Table->PreRSSI = curRSSI; + + //1 6.Set next timer + + if(pDM_SWAT_Table->RSSI_Trying == 0) + return; + + if(pDM_SWAT_Table->RSSI_Trying%2 == 0) + { + if(pDM_SWAT_Table->TestMode == TP_MODE) + { + if(TrafficLoad == TRAFFIC_HIGH) + { +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 10 ); //ms + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Test another antenna for 10 ms\n")); +#else + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 20 ); //ms + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Test another antenna for 20 ms\n")); +#endif + } + else if(TrafficLoad == TRAFFIC_LOW) + { + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 50 ); //ms + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Test another antenna for 50 ms\n")); + } + } + else // TestMode == RSSI_MODE + { + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 500 ); //ms + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Test another antenna for 500 ms\n")); + } + } + else + { + if(pDM_SWAT_Table->TestMode == TP_MODE) + { + if(TrafficLoad == TRAFFIC_HIGH) + +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 90 ); //ms + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("=PATH=: Test another antenna for 90 ms\n")); +#else + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 180); //ms +#endif + else if(TrafficLoad == TRAFFIC_LOW) + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 100 ); //ms + } + else + ODM_SetTimer( pDM_Odm, &pDM_Odm->PathDivSwitchTimer, 500 ); //ms + } +} + + + +VOID +ODM_CCKPathDiversityChkPerPktRssi( + PADAPTER Adapter, + BOOLEAN bIsDefPort, + BOOLEAN bMatchBSSID, + PRT_WLAN_STA pEntry, + PRT_RFD pRfd, + pu1Byte pDesc + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + BOOLEAN bCount = FALSE; + pPD_T pDM_PDTable = &Adapter->DM_PDTable; + //BOOLEAN isCCKrate = RX_HAL_IS_CCK_RATE_92C(pDesc); +#if DEV_BUS_TYPE != RT_SDIO_INTERFACE + BOOLEAN isCCKrate = RX_HAL_IS_CCK_RATE(Adapter, pDesc); +#else //below code would be removed if we have verified SDIO + BOOLEAN isCCKrate = IS_HARDWARE_TYPE_8188E(Adapter) ? RX_HAL_IS_CCK_RATE_88E(pDesc) : RX_HAL_IS_CCK_RATE_92C(pDesc); +#endif + + if((pHalData->PathDivCfg != 1) || (pHalData->RSSI_test == FALSE)) + return; + + if(pHalData->RSSI_target==NULL && bIsDefPort && bMatchBSSID) + bCount = TRUE; + else if(pHalData->RSSI_target!=NULL && pEntry!=NULL && pHalData->RSSI_target==pEntry) + bCount = TRUE; + + if(bCount && isCCKrate) + { + if(pDM_PDTable->TrainingState == 1 ) + { + if(pEntry) + { + if(pEntry->rssi_stat.RSSI_CCK_Path_cnt[0] != 0) + pEntry->rssi_stat.RSSI_CCK_Path[0] += pRfd->Status.RxPWDBAll; + pEntry->rssi_stat.RSSI_CCK_Path_cnt[0]++; + } + else + { + if(pDM_PDTable->RSSI_CCK_Path_cnt[0] != 0) + pDM_PDTable->RSSI_CCK_Path[0] += pRfd->Status.RxPWDBAll; + pDM_PDTable->RSSI_CCK_Path_cnt[0]++; + } + } + else if(pDM_PDTable->TrainingState == 2 ) + { + if(pEntry) + { + if(pEntry->rssi_stat.RSSI_CCK_Path_cnt[1] != 0) + pEntry->rssi_stat.RSSI_CCK_Path[1] += pRfd->Status.RxPWDBAll; + pEntry->rssi_stat.RSSI_CCK_Path_cnt[1]++; + } + else + { + if(pDM_PDTable->RSSI_CCK_Path_cnt[1] != 0) + pDM_PDTable->RSSI_CCK_Path[1] += pRfd->Status.RxPWDBAll; + pDM_PDTable->RSSI_CCK_Path_cnt[1]++; + } + } + } +} + + + + +//Neil Chen---2011--06--22 +//----92D Path Diversity----// +//#ifdef PathDiv92D +//================================== +//3 Path Diversity +//================================== +// +// 20100514 Luke/Joseph: +// Add new function for antenna diversity after link. +// This is the main function of antenna diversity after link. +// This function is called in HalDmWatchDog() and ODM_SwAntDivChkAntSwitchCallback(). +// HalDmWatchDog() calls this function with SWAW_STEP_PEAK to initialize the antenna test. +// In SWAW_STEP_PEAK, another antenna and a 500ms timer will be set for testing. +// After 500ms, ODM_SwAntDivChkAntSwitchCallback() calls this function to compare the signal just +// listened on the air with the RSSI of original antenna. +// It chooses the antenna with better RSSI. +// There is also a aged policy for error trying. Each error trying will cost more 5 seconds waiting +// penalty to get next try. +// +// +// 20100503 Joseph: +// Add new function SwAntDivCheck8192C(). +// This is the main function of Antenna diversity function before link. +// Mainly, it just retains last scan result and scan again. +// After that, it compares the scan result to see which one gets better RSSI. +// It selects antenna with better receiving power and returns better scan result. +// + + +// +// 20100514 Luke/Joseph: +// This function is used to gather the RSSI information for antenna testing. +// It selects the RSSI of the peer STA that we want to know. +// +VOID +ODM_PathDivChkPerPktRssi( + PADAPTER Adapter, + BOOLEAN bIsDefPort, + BOOLEAN bMatchBSSID, + PRT_WLAN_STA pEntry, + PRT_RFD pRfd + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + BOOLEAN bCount = FALSE; + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + + if(pHalData->RSSI_target==NULL && bIsDefPort && bMatchBSSID) + bCount = TRUE; + else if(pHalData->RSSI_target!=NULL && pEntry!=NULL && pHalData->RSSI_target==pEntry) + bCount = TRUE; + + if(bCount) + { + //1 RSSI for SW Antenna Switch + if(pDM_SWAT_Table->CurAntenna == MAIN_ANT) + { + pHalData->RSSI_sum_A += pRfd->Status.RxPWDBAll; + pHalData->RSSI_cnt_A++; + } + else + { + pHalData->RSSI_sum_B += pRfd->Status.RxPWDBAll; + pHalData->RSSI_cnt_B++; + + } + } +} + + +// +// 20100514 Luke/Joseph: +// Add new function to reset antenna diversity state after link. +// +VOID +ODM_PathDivRestAfterLink( + IN PDM_ODM_T pDM_Odm + ) +{ + PADAPTER Adapter=pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + + pHalData->RSSI_cnt_A = 0; + pHalData->RSSI_cnt_B = 0; + pHalData->RSSI_test = FALSE; + pDM_SWAT_Table->try_flag = 0x0; // NOT 0xff + pDM_SWAT_Table->RSSI_Trying = 0; + pDM_SWAT_Table->SelectAntennaMap=0xAA; + pDM_SWAT_Table->CurAntenna = MAIN_ANT; +} + + +//================================================== +//3 PathDiv End +//================================================== + + +VOID +ODM_FillTXPathInTXDESC( + IN PADAPTER Adapter, + IN PRT_TCB pTcb, + IN pu1Byte pDesc +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u4Byte TXPath; + pPD_T pDM_PDTable = &Adapter->DM_PDTable; + + //2011.09.05 Add by Luke Lee for path diversity + if(pHalData->PathDivCfg == 1) + { + TXPath = (pDM_PDTable->OFDMTXPath >> pTcb->macId) & BIT0; + //RT_TRACE( COMP_INIT, DBG_LOUD, ("Fill TXDESC: macID=%d, TXPath=%d\n", pTcb->macId, TXPath)); + //SET_TX_DESC_TX_ANT_CCK(pDesc,TXPath); + if(TXPath == 0) + { + SET_TX_DESC_TX_ANTL_92C(pDesc,1); + SET_TX_DESC_TX_ANT_HT_92C(pDesc,1); + } + else + { + SET_TX_DESC_TX_ANTL_92C(pDesc,2); + SET_TX_DESC_TX_ANT_HT_92C(pDesc,2); + } + TXPath = (pDM_PDTable->CCKTXPath >> pTcb->macId) & BIT0; + if(TXPath == 0) + { + SET_TX_DESC_TX_ANT_CCK_92C(pDesc,1); + } + else + { + SET_TX_DESC_TX_ANT_CCK_92C(pDesc,2); + } + } +} + +//Only for MP //Neil Chen--2012--0502-- +VOID +odm_PathDivInit_92D( +IN PDM_ODM_T pDM_Odm) +{ + pPATHDIV_PARA pathIQK = &pDM_Odm->pathIQK; + + pathIQK->org_2g_RegC14=0x0; + pathIQK->org_2g_RegC4C=0x0; + pathIQK->org_2g_RegC80=0x0; + pathIQK->org_2g_RegC94=0x0; + pathIQK->org_2g_RegCA0=0x0; + pathIQK->org_5g_RegC14=0x0; + pathIQK->org_5g_RegCA0=0x0; + pathIQK->org_5g_RegE30=0x0; + pathIQK->swt_2g_RegC14=0x0; + pathIQK->swt_2g_RegC4C=0x0; + pathIQK->swt_2g_RegC80=0x0; + pathIQK->swt_2g_RegC94=0x0; + pathIQK->swt_2g_RegCA0=0x0; + pathIQK->swt_5g_RegC14=0x0; + pathIQK->swt_5g_RegCA0=0x0; + pathIQK->swt_5g_RegE30=0x0; + +} + + +u1Byte +odm_SwAntDivSelectScanChnl( + IN PADAPTER Adapter + ) +{ +#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + u2Byte i; + u1Byte j, ScanChannel = 0, ChannelNum = 0; + PRT_CHANNEL_LIST pChannelList = GET_RT_CHANNEL_LIST(pMgntInfo); + u1Byte EachChannelSTAs[MAX_SCAN_CHANNEL_NUM] = {0}; + + if(pMgntInfo->tmpNumBssDesc == 0) + return 0; + + for(i = 0; i < pMgntInfo->tmpNumBssDesc; i++) + { + ChannelNum = pMgntInfo->tmpbssDesc[i].ChannelNumber; + for(j = 0; j < pChannelList->ChannelLen; j++) + { + if(pChannelList->ChnlListEntry[j].ChannelNum == ChannelNum) + { + EachChannelSTAs[j]++; + break; + } + } + } + + for(i = 0; i < MAX_SCAN_CHANNEL_NUM; i++) + { + if(EachChannelSTAs[i] > EachChannelSTAs[ScanChannel]) + ScanChannel = (u1Byte)i; + } + + if(EachChannelSTAs[ScanChannel] == 0) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("odm_SwAntDivSelectScanChnl(): Scan List is empty.\n")); + return 0; + } + + ScanChannel = pChannelList->ChnlListEntry[ScanChannel].ChannelNum; + + + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, + ("odm_SwAntDivSelectScanChnl(): Channel (( %d )) is select as scan channel.\n", ScanChannel)); + + return ScanChannel; +#else + return 0; +#endif +} + + +VOID +odm_SwAntDivConstructScanChnl( + IN PADAPTER Adapter, + IN u1Byte ScanChnl + ) +{ + + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + if(ScanChnl == 0) + { + u1Byte i; + PRT_CHANNEL_LIST pChannelList = GET_RT_CHANNEL_LIST(pMgntInfo); + + // 20100519 Joseph: Original antenna scanned nothing. + // Test antenna shall scan all channel with half period in this condition. + + RT_TRACE_F(COMP_SCAN, DBG_TRACE, (" RT_CHNL_LIST_ACTION_CONSTRUCT chnl %d \n", ScanChnl)); + + RtActChannelList(Adapter, RT_CHNL_LIST_ACTION_CONSTRUCT_SCAN_LIST, NULL, NULL); + for(i = 0; i < pChannelList->ChannelLen; i++) + pChannelList->ChnlListEntry[i].ScanPeriod /= 2; + } + else + { + // The using of this CustomizedScanRequest is a trick to rescan the two channels + // under the NORMAL scanning process. It will not affect MGNT_INFO.CustomizedScanRequest. + CUSTOMIZED_SCAN_REQUEST CustomScanReq; + + CustomScanReq.bEnabled = TRUE; + CustomScanReq.Channels[0] = ScanChnl; + CustomScanReq.Channels[1] = pMgntInfo->dot11CurrentChannelNumber; + CustomScanReq.nChannels = 2; + CustomScanReq.ScanType = SCAN_ACTIVE; + CustomScanReq.Duration = DEFAULT_PASSIVE_SCAN_PERIOD; + + RT_TRACE_F(COMP_SCAN, DBG_TRACE, (" RT_CHNL_LIST_ACTION_CONSTRUCT chnl %d \n", ScanChnl)); + + RtActChannelList(Adapter, RT_CHNL_LIST_ACTION_CONSTRUCT_SCAN_LIST, &CustomScanReq, NULL); + } + +} + + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PathDiv.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PathDiv.h new file mode 100755 index 000000000000..e72e937a7bf5 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PathDiv.h @@ -0,0 +1,193 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMPATHDIV_H__ +#define __PHYDMPATHDIV_H__ + +#define PATHDIV_VERSION "1.0" + +VOID +odm_PathDiversityInit( + IN PVOID pDM_VOID + ); + +VOID +odm_PathDiversity( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + +//#define PATHDIV_ENABLE 1 +#define dm_PathDiv_RSSI_Check ODM_PathDivChkPerPktRssi +#define PathDivCheckBeforeLink8192C ODM_PathDiversityBeforeLink92C + +typedef struct _PathDiv_Parameter_define_ +{ + u4Byte org_5g_RegE30; + u4Byte org_5g_RegC14; + u4Byte org_5g_RegCA0; + u4Byte swt_5g_RegE30; + u4Byte swt_5g_RegC14; + u4Byte swt_5g_RegCA0; + //for 2G IQK information + u4Byte org_2g_RegC80; + u4Byte org_2g_RegC4C; + u4Byte org_2g_RegC94; + u4Byte org_2g_RegC14; + u4Byte org_2g_RegCA0; + + u4Byte swt_2g_RegC80; + u4Byte swt_2g_RegC4C; + u4Byte swt_2g_RegC94; + u4Byte swt_2g_RegC14; + u4Byte swt_2g_RegCA0; +}PATHDIV_PARA,*pPATHDIV_PARA; + +VOID +odm_PathDiversityInit_92C( + IN PADAPTER Adapter + ); + +VOID +odm_2TPathDiversityInit_92C( + IN PADAPTER Adapter + ); + +VOID +odm_1TPathDiversityInit_92C( + IN PADAPTER Adapter + ); + +BOOLEAN +odm_IsConnected_92C( + IN PADAPTER Adapter + ); + +BOOLEAN +ODM_PathDiversityBeforeLink92C( + //IN PADAPTER Adapter + IN PDM_ODM_T pDM_Odm + ); + +VOID +odm_PathDiversityAfterLink_92C( + IN PADAPTER Adapter + ); + +VOID +odm_SetRespPath_92C( + IN PADAPTER Adapter, + IN u1Byte DefaultRespPath + ); + +VOID +odm_OFDMTXPathDiversity_92C( + IN PADAPTER Adapter + ); + +VOID +odm_CCKTXPathDiversity_92C( + IN PADAPTER Adapter + ); + +VOID +odm_ResetPathDiversity_92C( + IN PADAPTER Adapter + ); + +VOID +odm_CCKTXPathDiversityCallback( + PRT_TIMER pTimer + ); + +VOID +odm_CCKTXPathDiversityWorkItemCallback( + IN PVOID pContext + ); + +VOID +odm_PathDivChkAntSwitchCallback( + PRT_TIMER pTimer + ); + +VOID +odm_PathDivChkAntSwitchWorkitemCallback( + IN PVOID pContext + ); + + +VOID +odm_PathDivChkAntSwitch( + PDM_ODM_T pDM_Odm + ); + +VOID +ODM_CCKPathDiversityChkPerPktRssi( + PADAPTER Adapter, + BOOLEAN bIsDefPort, + BOOLEAN bMatchBSSID, + PRT_WLAN_STA pEntry, + PRT_RFD pRfd, + pu1Byte pDesc + ); + +VOID +ODM_PathDivChkPerPktRssi( + PADAPTER Adapter, + BOOLEAN bIsDefPort, + BOOLEAN bMatchBSSID, + PRT_WLAN_STA pEntry, + PRT_RFD pRfd + ); + +VOID +ODM_PathDivRestAfterLink( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_FillTXPathInTXDESC( + IN PADAPTER Adapter, + IN PRT_TCB pTcb, + IN pu1Byte pDesc + ); + +VOID +odm_PathDivInit_92D( + IN PDM_ODM_T pDM_Odm + ); + +u1Byte +odm_SwAntDivSelectScanChnl( + IN PADAPTER Adapter + ); + +VOID +odm_SwAntDivConstructScanChnl( + IN PADAPTER Adapter, + IN u1Byte ScanChnl + ); + + #endif //#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + + + #endif //#ifndef __ODMPATHDIV_H__ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PowerTracking.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PowerTracking.c new file mode 100755 index 000000000000..507b250ec174 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PowerTracking.c @@ -0,0 +1,687 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +//============================================================ +// Global var +//============================================================ + +u4Byte OFDMSwingTable[OFDM_TABLE_SIZE] = { + 0x7f8001fe, // 0, +6.0dB + 0x788001e2, // 1, +5.5dB + 0x71c001c7, // 2, +5.0dB + 0x6b8001ae, // 3, +4.5dB + 0x65400195, // 4, +4.0dB + 0x5fc0017f, // 5, +3.5dB + 0x5a400169, // 6, +3.0dB + 0x55400155, // 7, +2.5dB + 0x50800142, // 8, +2.0dB + 0x4c000130, // 9, +1.5dB + 0x47c0011f, // 10, +1.0dB + 0x43c0010f, // 11, +0.5dB + 0x40000100, // 12, +0dB + 0x3c8000f2, // 13, -0.5dB + 0x390000e4, // 14, -1.0dB + 0x35c000d7, // 15, -1.5dB + 0x32c000cb, // 16, -2.0dB + 0x300000c0, // 17, -2.5dB + 0x2d4000b5, // 18, -3.0dB + 0x2ac000ab, // 19, -3.5dB + 0x288000a2, // 20, -4.0dB + 0x26000098, // 21, -4.5dB + 0x24000090, // 22, -5.0dB + 0x22000088, // 23, -5.5dB + 0x20000080, // 24, -6.0dB + 0x1e400079, // 25, -6.5dB + 0x1c800072, // 26, -7.0dB + 0x1b00006c, // 27. -7.5dB + 0x19800066, // 28, -8.0dB + 0x18000060, // 29, -8.5dB + 0x16c0005b, // 30, -9.0dB + 0x15800056, // 31, -9.5dB + 0x14400051, // 32, -10.0dB + 0x1300004c, // 33, -10.5dB + 0x12000048, // 34, -11.0dB + 0x11000044, // 35, -11.5dB + 0x10000040, // 36, -12.0dB +}; + +u1Byte CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, // 0, +0dB + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, // 1, -0.5dB + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 2, -1.0dB + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, // 3, -1.5dB + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 4, -2.0dB + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, // 5, -2.5dB + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 6, -3.0dB + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, // 7, -3.5dB + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 8, -4.0dB + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, // 9, -4.5dB + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 10, -5.0dB + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, // 11, -5.5dB + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 12, -6.0dB <== default + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, // 13, -6.5dB + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 14, -7.0dB + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, // 15, -7.5dB + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 16, -8.0dB + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, // 17, -8.5dB + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 18, -9.0dB + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 19, -9.5dB + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 20, -10.0dB + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, // 21, -10.5dB + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, // 22, -11.0dB + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, // 23, -11.5dB + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, // 24, -12.0dB + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, // 25, -12.5dB + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, // 26, -13.0dB + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, // 27, -13.5dB + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, // 28, -14.0dB + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, // 29, -14.5dB + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, // 30, -15.0dB + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, // 31, -15.5dB + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} // 32, -16.0dB +}; + + +u1Byte CCKSwingTable_Ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, // 0, +0dB + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, // 1, -0.5dB + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 2, -1.0dB + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, // 3, -1.5dB + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 4, -2.0dB + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, // 5, -2.5dB + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 6, -3.0dB + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, // 7, -3.5dB + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 8, -4.0dB + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, // 9, -4.5dB + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 10, -5.0dB + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 11, -5.5dB + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 12, -6.0dB <== default + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, // 13, -6.5dB + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 14, -7.0dB + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 15, -7.5dB + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 16, -8.0dB + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 17, -8.5dB + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 18, -9.0dB + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 19, -9.5dB + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 20, -10.0dB + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, // 21, -10.5dB + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, // 22, -11.0dB + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, // 23, -11.5dB + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, // 24, -12.0dB + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, // 25, -12.5dB + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, // 26, -13.0dB + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, // 27, -13.5dB + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, // 28, -14.0dB + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, // 29, -14.5dB + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, // 30, -15.0dB + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, // 31, -15.5dB + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} // 32, -16.0dB +}; + + +u4Byte OFDMSwingTable_New[OFDM_TABLE_SIZE] = { + 0x0b40002d, // 0, -15.0dB + 0x0c000030, // 1, -14.5dB + 0x0cc00033, // 2, -14.0dB + 0x0d800036, // 3, -13.5dB + 0x0e400039, // 4, -13.0dB + 0x0f00003c, // 5, -12.5dB + 0x10000040, // 6, -12.0dB + 0x11000044, // 7, -11.5dB + 0x12000048, // 8, -11.0dB + 0x1300004c, // 9, -10.5dB + 0x14400051, // 10, -10.0dB + 0x15800056, // 11, -9.5dB + 0x16c0005b, // 12, -9.0dB + 0x18000060, // 13, -8.5dB + 0x19800066, // 14, -8.0dB + 0x1b00006c, // 15, -7.5dB + 0x1c800072, // 16, -7.0dB + 0x1e400079, // 17, -6.5dB + 0x20000080, // 18, -6.0dB + 0x22000088, // 19, -5.5dB + 0x24000090, // 20, -5.0dB + 0x26000098, // 21, -4.5dB + 0x288000a2, // 22, -4.0dB + 0x2ac000ab, // 23, -3.5dB + 0x2d4000b5, // 24, -3.0dB + 0x300000c0, // 25, -2.5dB + 0x32c000cb, // 26, -2.0dB + 0x35c000d7, // 27, -1.5dB + 0x390000e4, // 28, -1.0dB + 0x3c8000f2, // 29, -0.5dB + 0x40000100, // 30, +0dB + 0x43c0010f, // 31, +0.5dB + 0x47c0011f, // 32, +1.0dB + 0x4c000130, // 33, +1.5dB + 0x50800142, // 34, +2.0dB + 0x55400155, // 35, +2.5dB + 0x5a400169, // 36, +3.0dB + 0x5fc0017f, // 37, +3.5dB + 0x65400195, // 38, +4.0dB + 0x6b8001ae, // 39, +4.5dB + 0x71c001c7, // 40, +5.0dB + 0x788001e2, // 41, +5.5dB + 0x7f8001fe // 42, +6.0dB +}; + + +u1Byte CCKSwingTable_Ch1_Ch13_New[CCK_TABLE_SIZE][8] = { + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, // 0, -16.0dB + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, // 1, -15.5dB + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, // 2, -15.0dB + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, // 3, -14.5dB + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, // 4, -14.0dB + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, // 5, -13.5dB + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, // 6, -13.0dB + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, // 7, -12.5dB + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, // 8, -12.0dB + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, // 9, -11.5dB + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, // 10, -11.0dB + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, // 11, -10.5dB + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 12, -10.0dB + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 13, -9.5dB + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 14, -9.0dB + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, // 15, -8.5dB + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 16, -8.0dB + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, // 17, -7.5dB + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 18, -7.0dB + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, // 19, -6.5dB + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 20, -6.0dB + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, // 21, -5.5dB + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 22, -5.0dB + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, // 23, -4.5dB + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 24, -4.0dB + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, // 25, -3.5dB + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 26, -3.0dB + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, // 27, -2.5dB + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 28, -2.0dB + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, // 29, -1.5dB + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 30, -1.0dB + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, // 31, -0.5dB + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} // 32, +0dB +}; + + +u1Byte CCKSwingTable_Ch14_New[CCK_TABLE_SIZE][8]= { + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, // 0, -16.0dB + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, // 1, -15.5dB + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, // 2, -15.0dB + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, // 3, -14.5dB + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, // 4, -14.0dB + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, // 5, -13.5dB + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, // 6, -13.0dB + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, // 7, -12.5dB + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, // 8, -12.0dB + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, // 9, -11.5dB + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, // 10, -11.0dB + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, // 11, -10.5dB + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 12, -10.0dB + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 13, -9.5dB + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 14, -9.0dB + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 15, -8.5dB + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 16, -8.0dB + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 17, -7.5dB + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 18, -7.0dB + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, // 19, -6.5dB + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 20, -6.0dB + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 21, -5.5dB + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 22, -5.0dB + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, // 23, -4.5dB + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 24, -4.0dB + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, // 25, -3.5dB + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 26, -3.0dB + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, // 27, -2.5dB + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 28, -2.0dB + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, // 29, -1.5dB + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 30, -1.0dB + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, // 31, -0.5dB + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} // 32, +0dB +}; + +u4Byte TxScalingTable_Jaguar[TXSCALE_TABLE_SIZE] = +{ + 0x081, // 0, -12.0dB + 0x088, // 1, -11.5dB + 0x090, // 2, -11.0dB + 0x099, // 3, -10.5dB + 0x0A2, // 4, -10.0dB + 0x0AC, // 5, -9.5dB + 0x0B6, // 6, -9.0dB + 0x0C0, // 7, -8.5dB + 0x0CC, // 8, -8.0dB + 0x0D8, // 9, -7.5dB + 0x0E5, // 10, -7.0dB + 0x0F2, // 11, -6.5dB + 0x101, // 12, -6.0dB + 0x110, // 13, -5.5dB + 0x120, // 14, -5.0dB + 0x131, // 15, -4.5dB + 0x143, // 16, -4.0dB + 0x156, // 17, -3.5dB + 0x16A, // 18, -3.0dB + 0x180, // 19, -2.5dB + 0x197, // 20, -2.0dB + 0x1AF, // 21, -1.5dB + 0x1C8, // 22, -1.0dB + 0x1E3, // 23, -0.5dB + 0x200, // 24, +0 dB + 0x21E, // 25, +0.5dB + 0x23E, // 26, +1.0dB + 0x261, // 27, +1.5dB + 0x285, // 28, +2.0dB + 0x2AB, // 29, +2.5dB + 0x2D3, // 30, +3.0dB + 0x2FE, // 31, +3.5dB + 0x32B, // 32, +4.0dB + 0x35C, // 33, +4.5dB + 0x38E, // 34, +5.0dB + 0x3C4, // 35, +5.5dB + 0x3FE // 36, +6.0dB +}; + +#ifdef AP_BUILD_WORKAROUND + +unsigned int TxPwrTrk_OFDM_SwingTbl[TxPwrTrk_OFDM_SwingTbl_Len] = { + /* +6.0dB */ 0x7f8001fe, + /* +5.5dB */ 0x788001e2, + /* +5.0dB */ 0x71c001c7, + /* +4.5dB */ 0x6b8001ae, + /* +4.0dB */ 0x65400195, + /* +3.5dB */ 0x5fc0017f, + /* +3.0dB */ 0x5a400169, + /* +2.5dB */ 0x55400155, + /* +2.0dB */ 0x50800142, + /* +1.5dB */ 0x4c000130, + /* +1.0dB */ 0x47c0011f, + /* +0.5dB */ 0x43c0010f, + /* 0.0dB */ 0x40000100, + /* -0.5dB */ 0x3c8000f2, + /* -1.0dB */ 0x390000e4, + /* -1.5dB */ 0x35c000d7, + /* -2.0dB */ 0x32c000cb, + /* -2.5dB */ 0x300000c0, + /* -3.0dB */ 0x2d4000b5, + /* -3.5dB */ 0x2ac000ab, + /* -4.0dB */ 0x288000a2, + /* -4.5dB */ 0x26000098, + /* -5.0dB */ 0x24000090, + /* -5.5dB */ 0x22000088, + /* -6.0dB */ 0x20000080, + /* -6.5dB */ 0x1a00006c, + /* -7.0dB */ 0x1c800072, + /* -7.5dB */ 0x18000060, + /* -8.0dB */ 0x19800066, + /* -8.5dB */ 0x15800056, + /* -9.0dB */ 0x26c0005b, + /* -9.5dB */ 0x14400051, + /* -10.0dB */ 0x24400051, + /* -10.5dB */ 0x1300004c, + /* -11.0dB */ 0x12000048, + /* -11.5dB */ 0x11000044, + /* -12.0dB */ 0x10000040 +}; +#endif + + + +VOID +odm_TXPowerTrackingInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + if(!(pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_IC_11N_SERIES))) + return; +#endif + + odm_TXPowerTrackingThermalMeterInit(pDM_Odm); +} + +u1Byte +getSwingIndex( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u1Byte i = 0; + u4Byte bbSwing; + u4Byte swingTableSize; + pu4Byte pSwingTable; + + if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8723B || + pDM_Odm->SupportICType == ODM_RTL8192E) + { + bbSwing = PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, 0xFFC00000); + + pSwingTable = OFDMSwingTable_New; + swingTableSize = OFDM_TABLE_SIZE; + } else { +#if ((RTL8812A_SUPPORT==1)||(RTL8821A_SUPPORT==1)) + if (pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8821) + { + bbSwing = PHY_GetTxBBSwing_8812A(Adapter, pHalData->CurrentBandType, ODM_RF_PATH_A); + pSwingTable = TxScalingTable_Jaguar; + swingTableSize = TXSCALE_TABLE_SIZE; + } + else +#endif + { + bbSwing = 0; + pSwingTable = OFDMSwingTable; + swingTableSize = OFDM_TABLE_SIZE; + } + } + + for (i = 0; i < swingTableSize; ++i) { + u4Byte tableValue = pSwingTable[i]; + + if (tableValue >= 0x100000 ) + tableValue >>= 22; + if (bbSwing == tableValue) + break; + } + return i; +} + +VOID +odm_TXPowerTrackingThermalMeterInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte defaultSwingIndex = getSwingIndex(pDM_Odm); + u1Byte p = 0; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(pDM_Odm->mp_mode == FALSE) + pHalData->TxPowerTrackControl = TRUE; +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + + if (pDM_Odm->SupportICType >= ODM_RTL8188E) + { + pDM_Odm->RFCalibrateInfo.bTXPowerTracking = _TRUE; + pDM_Odm->RFCalibrateInfo.TXPowercount = 0; + pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = _FALSE; + + if(pDM_Odm->mp_mode == FALSE) + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _TRUE; + else + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _FALSE; + + MSG_8192C("pDM_Odm TxPowerTrackControl = %d\n", pDM_Odm->RFCalibrateInfo.TxPowerTrackControl); + } + else + { + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + pdmpriv->bTXPowerTracking = _TRUE; + pdmpriv->TXPowercount = 0; + pdmpriv->bTXPowerTrackingInit = _FALSE; + //#if (MP_DRIVER != 1) //for mp driver, turn off txpwrtracking as default + + if(pDM_Odm->mp_mode == FALSE) + pdmpriv->TxPowerTrackControl = _TRUE; + else + pdmpriv->TxPowerTrackControl = _FALSE; + + + //MSG_8192C("pdmpriv->TxPowerTrackControl = %d\n", pdmpriv->TxPowerTrackControl); + } + +#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + #ifdef RTL8188E_SUPPORT + { + pDM_Odm->RFCalibrateInfo.bTXPowerTracking = _TRUE; + pDM_Odm->RFCalibrateInfo.TXPowercount = 0; + pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = _FALSE; + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _TRUE; + } + #endif +#endif + + //pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = TRUE; + pDM_Odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter; + pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = pHalData->EEPROMThermalMeter; + pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = pHalData->EEPROMThermalMeter; + + // The index of "0 dB" in SwingTable. + if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8723B || + pDM_Odm->SupportICType == ODM_RTL8192E) + { + pDM_Odm->DefaultOfdmIndex = (defaultSwingIndex >= OFDM_TABLE_SIZE) ? 30 : defaultSwingIndex; + pDM_Odm->DefaultCckIndex = 20; + } + else + { + pDM_Odm->DefaultOfdmIndex = (defaultSwingIndex >= TXSCALE_TABLE_SIZE) ? 24 : defaultSwingIndex; + pDM_Odm->DefaultCckIndex = 24; + } + + pDM_Odm->BbSwingIdxCckBase = pDM_Odm->DefaultCckIndex; + pDM_Odm->RFCalibrateInfo.CCK_index = pDM_Odm->DefaultCckIndex; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) + { + pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->DefaultOfdmIndex; + pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pDM_Odm->DefaultOfdmIndex; + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = 0; + pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = 0; + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0; + } + +} + + +VOID +ODM_TXPowerTrackingCheck( + IN PVOID pDM_VOID + ) +{ + // + // 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate + // at the same time. In the stage2/3, we need to prive universal interface and merge all + // HW dynamic mechanism. + // + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + switch (pDM_Odm->SupportPlatform) + { + case ODM_WIN: + odm_TXPowerTrackingCheckMP(pDM_Odm); + break; + + case ODM_CE: + odm_TXPowerTrackingCheckCE(pDM_Odm); + break; + + case ODM_AP: + odm_TXPowerTrackingCheckAP(pDM_Odm); + break; + + case ODM_ADSL: + //odm_DIGAP(pDM_Odm); + break; + } + +} + +VOID +odm_TXPowerTrackingCheckCE( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + #if( (RTL8192C_SUPPORT==1) || (RTL8723A_SUPPORT==1) ) + if(IS_HARDWARE_TYPE_8192C(Adapter)){ + rtl8192c_odm_CheckTXPowerTracking(Adapter); + return; + } + #endif + + #if (RTL8192D_SUPPORT==1) + if(IS_HARDWARE_TYPE_8192D(Adapter)){ + #if (RTL8192D_EASY_SMART_CONCURRENT == 1) + if(!Adapter->bSlaveOfDMSP) + #endif + rtl8192d_odm_CheckTXPowerTracking(Adapter); + return; + } + #endif + + #if(((RTL8188E_SUPPORT==1) || (RTL8812A_SUPPORT==1) || (RTL8821A_SUPPORT==1) || (RTL8192E_SUPPORT==1) || (RTL8723B_SUPPORT==1) )) + if(!(pDM_Odm->SupportAbility & ODM_RF_TX_PWR_TRACK)) + { + return; + } + + if(!pDM_Odm->RFCalibrateInfo.TM_Trigger) //at least delay 1 sec + { + //pHalData->TxPowerCheckCnt++; //cosa add for debug + if(IS_HARDWARE_TYPE_8188E(Adapter) || IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter)||IS_HARDWARE_TYPE_8723B(Adapter)) + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_T_METER_NEW, (BIT17 | BIT16), 0x03); + else + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_T_METER_OLD, bRFRegOffsetMask, 0x60); + + //DBG_871X("Trigger Thermal Meter!!\n"); + + pDM_Odm->RFCalibrateInfo.TM_Trigger = 1; + return; + } + else + { + //DBG_871X("Schedule TxPowerTracking direct call!!\n"); + ODM_TXPowerTrackingCallback_ThermalMeter(Adapter); + pDM_Odm->RFCalibrateInfo.TM_Trigger = 0; + } + #endif +#endif +} + +VOID +odm_TXPowerTrackingCheckMP( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + + if (ODM_CheckPowerStatus(Adapter) == FALSE) + { + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("===>ODM_CheckPowerStatus() return FALSE\n")); + return; + } + + if(IS_HARDWARE_TYPE_8723A(Adapter)) + return; + + if(!Adapter->bSlaveOfDMSP || Adapter->DualMacSmartConcurrent == FALSE) + odm_TXPowerTrackingThermalMeterCheck(Adapter); + else { + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("!Adapter->bSlaveOfDMSP || Adapter->DualMacSmartConcurrent == FALSE\n")); + } +#endif + +} + + +VOID +odm_TXPowerTrackingCheckAP( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + prtl8192cd_priv priv = pDM_Odm->priv; + + if ( (priv->pmib->dot11RFEntry.ther) && ((priv->up_time % priv->pshare->rf_ft_var.tpt_period) == 0)){ +#ifdef CONFIG_RTL_92D_SUPPORT + if (GET_CHIP_VER(priv)==VERSION_8192D){ + tx_power_tracking_92D(priv); + } else +#endif + { +#ifdef CONFIG_RTL_92C_SUPPORT + tx_power_tracking(priv); +#endif + } + } +#endif + +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +odm_TXPowerTrackingThermalMeterCheck( + IN PADAPTER Adapter + ) +{ +#ifndef AP_BUILD_WORKAROUND + static u1Byte TM_Trigger = 0; + + if(!(GET_HAL_DATA(Adapter)->DM_OutSrc.SupportAbility & ODM_RF_TX_PWR_TRACK)) + { + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, + ("===>odm_TXPowerTrackingThermalMeterCheck(),pMgntInfo->bTXPowerTracking is FALSE, return!!\n")); + return; + } + + if(!TM_Trigger) //at least delay 1 sec + { + if(IS_HARDWARE_TYPE_8192D(Adapter)) + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, RF_T_METER_92D, BIT17 | BIT16, 0x03); + else if(IS_HARDWARE_TYPE_8188E(Adapter) || IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter) || + IS_HARDWARE_TYPE_8723B(Adapter)) + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, RF_T_METER_88E, BIT17 | BIT16, 0x03); + else + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); + + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,("Trigger Thermal Meter!!\n")); + + TM_Trigger = 1; + return; + } + else + { + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,("Schedule TxPowerTracking direct call!!\n")); + odm_TXPowerTrackingDirectCall(Adapter); //Using direct call is instead, added by Roger, 2009.06.18. + TM_Trigger = 0; + } +#endif +} +#endif + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PowerTracking.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PowerTracking.h new file mode 100755 index 000000000000..727cdb14a816 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_PowerTracking.h @@ -0,0 +1,248 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMPOWERTRACKING_H__ +#define __PHYDMPOWERTRACKING_H__ + +#define POWRTRACKING_VERSION "1.0" + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#define TXSCALE_TABLE_SIZE 37 +#define TXPWR_TRACK_TABLE_SIZE 30 +#define DELTA_SWINGIDX_SIZE 30 +#define BAND_NUM 4 + +#define AVG_THERMAL_NUM 8 +#define HP_THERMAL_NUM 8 +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM_MAX 10 +#if (RTL8192D_SUPPORT==1) +#define IQK_BB_REG_NUM 10 +#else +#define IQK_BB_REG_NUM 9 +#endif + + +#define IQK_Matrix_REG_NUM 8 +#define IQK_Matrix_Settings_NUM 14+24+21 // Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G + +extern u4Byte OFDMSwingTable[OFDM_TABLE_SIZE]; +extern u1Byte CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8]; +extern u1Byte CCKSwingTable_Ch14 [CCK_TABLE_SIZE][8]; + +extern u4Byte OFDMSwingTable_New[OFDM_TABLE_SIZE]; +extern u1Byte CCKSwingTable_Ch1_Ch13_New[CCK_TABLE_SIZE][8]; +extern u1Byte CCKSwingTable_Ch14_New [CCK_TABLE_SIZE][8]; + +extern u4Byte TxScalingTable_Jaguar[TXSCALE_TABLE_SIZE]; + +// <20121018, Kordan> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. +static u1Byte DeltaSwingTableIdx_2GA_P_8188E[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9}; +static u1Byte DeltaSwingTableIdx_2GA_N_8188E[] = {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11}; + +#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck + +typedef struct _IQK_MATRIX_REGS_SETTING{ + BOOLEAN bIQKDone; + s4Byte Value[3][IQK_Matrix_REG_NUM]; + BOOLEAN bBWIqkResultSaved[3]; +}IQK_MATRIX_REGS_SETTING,*PIQK_MATRIX_REGS_SETTING; + +typedef struct ODM_RF_Calibration_Structure +{ + //for tx power tracking + + u4Byte RegA24; // for TempCCK + s4Byte RegE94; + s4Byte RegE9C; + s4Byte RegEB4; + s4Byte RegEBC; + + u1Byte TXPowercount; + BOOLEAN bTXPowerTrackingInit; + BOOLEAN bTXPowerTracking; + u1Byte TxPowerTrackControl; //for mp mode, turn off txpwrtracking as default + u1Byte TM_Trigger; + u1Byte InternalPA5G[2]; //pathA / pathB + + u1Byte ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 + u1Byte ThermalValue; + u1Byte ThermalValue_LCK; + u1Byte ThermalValue_IQK; + u1Byte ThermalValue_DPK; + u1Byte ThermalValue_AVG[AVG_THERMAL_NUM]; + u1Byte ThermalValue_AVG_index; + u1Byte ThermalValue_RxGain; + u1Byte ThermalValue_Crystal; + u1Byte ThermalValue_DPKstore; + u1Byte ThermalValue_DPKtrack; + BOOLEAN TxPowerTrackingInProgress; + + BOOLEAN bReloadtxpowerindex; + u1Byte bRfPiEnable; + u4Byte TXPowerTrackingCallbackCnt; //cosa add for debug + + + //------------------------- Tx power Tracking -------------------------// + u1Byte bCCKinCH14; + u1Byte CCK_index; + u1Byte OFDM_index[MAX_RF_PATH]; + s1Byte PowerIndexOffset[MAX_RF_PATH]; + s1Byte DeltaPowerIndex[MAX_RF_PATH]; + s1Byte DeltaPowerIndexLast[MAX_RF_PATH]; + BOOLEAN bTxPowerChanged; + + u1Byte ThermalValue_HP[HP_THERMAL_NUM]; + u1Byte ThermalValue_HP_index; + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; + u1Byte Delta_LCK; + s1Byte BBSwingDiff2G, BBSwingDiff5G; // Unit: dB + u1Byte DeltaSwingTableIdx_2GCCKA_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKA_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKB_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKB_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GB_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GB_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GA_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GA_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GB_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GB_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_P_8188E[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_N_8188E[DELTA_SWINGIDX_SIZE]; + + + //--------------------------------------------------------------------// + + //for IQK + u4Byte RegC04; + u4Byte Reg874; + u4Byte RegC08; + u4Byte RegB68; + u4Byte RegB6C; + u4Byte Reg870; + u4Byte Reg860; + u4Byte Reg864; + + BOOLEAN bIQKInitialized; + BOOLEAN bLCKInProgress; + BOOLEAN bAntennaDetected; + BOOLEAN bNeedIQK; + BOOLEAN bIQKInProgress; + u1Byte Delta_IQK; + u4Byte ADDA_backup[IQK_ADDA_REG_NUM]; + u4Byte IQK_MAC_backup[IQK_MAC_REG_NUM]; + u4Byte IQK_BB_backup_recover[9]; + u4Byte IQK_BB_backup[IQK_BB_REG_NUM]; + u4Byte TxIQC_8723B[2][3][2]; // { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} + u4Byte RxIQC_8723B[2][2][2]; // { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} + + // IQK time measurement + u8Byte IQK_StartTime; + u8Byte IQK_ProgressingTime; + + //for APK + u4Byte APKoutput[2][2]; //path A/B; output1_1a/output1_2a + u1Byte bAPKdone; + u1Byte bAPKThermalMeterIgnore; + + // DPK + BOOLEAN bDPKFail; + u1Byte bDPdone; + u1Byte bDPPathAOK; + u1Byte bDPPathBOK; + + u4Byte TxLOK[2]; + +}ODM_RF_CAL_T,*PODM_RF_CAL_T; + + +VOID +ODM_TXPowerTrackingCheck( + IN PVOID pDM_VOID + ); + + +VOID +odm_TXPowerTrackingInit( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingCheckAP( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingThermalMeterInit( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingInit( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingCheckMP( + IN PVOID pDM_VOID + ); + + +VOID +odm_TXPowerTrackingCheckCE( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + +VOID +odm_TXPowerTrackingCallbackThermalMeter92C( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingCallbackRXGainThermalMeter92D( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingCallbackThermalMeter92D( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingDirectCall92C( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingThermalMeterCheck( + IN PADAPTER Adapter + ); + +#endif + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RXHP.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RXHP.c new file mode 100755 index 000000000000..fcdcb0eca354 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RXHP.c @@ -0,0 +1,1685 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#define AFH_PSD 1 //0:normal PSD scan, 1: only do 20 pts PSD +#define MODE_40M 0 //0:20M, 1:40M +#define PSD_TH2 3 +#define PSD_CHMIN 20 // Minimum channel number for BT AFH +#define SIR_STEP_SIZE 3 +#define Smooth_Size_1 5 +#define Smooth_TH_1 3 +#define Smooth_Size_2 10 +#define Smooth_TH_2 4 +#define Smooth_Size_3 20 +#define Smooth_TH_3 4 +#define Smooth_Step_Size 5 +#define Adaptive_SIR 1 +#define SCAN_INTERVAL 1500 //ms +#define SYN_Length 5 // for 92D + +#define LNA_Low_Gain_1 0x64 +#define LNA_Low_Gain_2 0x5A +#define LNA_Low_Gain_3 0x58 + +#define pw_th_10dB 0x0 +#define pw_th_16dB 0x3 + +#define FA_RXHP_TH1 5000 +#define FA_RXHP_TH2 1500 +#define FA_RXHP_TH3 800 +#define FA_RXHP_TH4 600 +#define FA_RXHP_TH5 500 + +#define Idle_Mode 0 +#define High_TP_Mode 1 +#define Low_TP_Mode 2 + + +VOID +odm_PSDMonitorInit( + IN PVOID pDM_VOID + ) +{ +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)|(DEV_BUS_TYPE == RT_USB_INTERFACE) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //PSD Monitor Setting + //Which path in ADC/DAC is turnned on for PSD: both I/Q + ODM_SetBBReg(pDM_Odm, ODM_PSDREG, BIT10|BIT11, 0x3); + //Ageraged number: 8 + ODM_SetBBReg(pDM_Odm, ODM_PSDREG, BIT12|BIT13, 0x1); + pDM_Odm->bPSDinProcess = FALSE; + pDM_Odm->bUserAssignLevel = FALSE; + pDM_Odm->bPSDactive = FALSE; + //pDM_Odm->bDMInitialGainEnable=TRUE; //change the initialization to DIGinit + //Set Debug Port + //PHY_SetBBReg(Adapter, 0x908, bMaskDWord, 0x803); + //PHY_SetBBReg(Adapter, 0xB34, bMaskByte0, 0x00); // pause PSD + //PHY_SetBBReg(Adapter, 0xB38, bMaskByte0, 10); //rescan + //PHY_SetBBReg(Adapter, 0xB38, bMaskByte2|bMaskByte3, 100); //interval + + //PlatformSetTimer( Adapter, &pHalData->PSDTriggerTimer, 0); //ms +#endif +} + +VOID +PatchDCTone( + IN PVOID pDM_VOID, + pu4Byte PSD_report, + u1Byte initial_gain_psd +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //PADAPTER pAdapter; + + u4Byte psd_report; + + //2 Switch to CH11 to patch CH9 and CH13 DC tone + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, 11); + + if(pDM_Odm->SupportICType== ODM_RTL8192D) + { + if((*(pDM_Odm->pMacPhyMode) == ODM_SMSP)||(*(pDM_Odm->pMacPhyMode) == ODM_DMSP)) + { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_CHNLBW, 0x3FF, 11); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x25, 0xfffff, 0x643BC); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x26, 0xfffff, 0xFC038); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x27, 0xfffff, 0x77C1A); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x2B, 0xfffff, 0x41289); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x2C, 0xfffff, 0x01840); + } + else + { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x25, 0xfffff, 0x643BC); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x26, 0xfffff, 0xFC038); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x27, 0xfffff, 0x77C1A); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x2B, 0xfffff, 0x41289); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x2C, 0xfffff, 0x01840); + } + } + + //Ch9 DC tone patch + psd_report = GetPSDData(pDM_Odm, 96, initial_gain_psd); + PSD_report[50] = psd_report; + //Ch13 DC tone patch + psd_report = GetPSDData(pDM_Odm, 32, initial_gain_psd); + PSD_report[70] = psd_report; + + //2 Switch to CH3 to patch CH1 and CH5 DC tone + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, 3); + + + if(pDM_Odm->SupportICType==ODM_RTL8192D) + { + if((*(pDM_Odm->pMacPhyMode) == ODM_SMSP)||(*(pDM_Odm->pMacPhyMode) == ODM_DMSP)) + { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_CHNLBW, 0x3FF, 3); + //PHY_SetRFReg(Adapter, ODM_RF_PATH_B, 0x25, 0xfffff, 0x643BC); + //PHY_SetRFReg(Adapter, ODM_RF_PATH_B, 0x26, 0xfffff, 0xFC038); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x27, 0xfffff, 0x07C1A); + //PHY_SetRFReg(Adapter, ODM_RF_PATH_B, 0x2B, 0xfffff, 0x61289); + //PHY_SetRFReg(Adapter, ODM_RF_PATH_B, 0x2C, 0xfffff, 0x01C41); + } + else + { + //PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x25, 0xfffff, 0x643BC); + //PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x26, 0xfffff, 0xFC038); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x27, 0xfffff, 0x07C1A); + //PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x2B, 0xfffff, 0x61289); + //PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x2C, 0xfffff, 0x01C41); + } + } + + //Ch1 DC tone patch + psd_report = GetPSDData(pDM_Odm, 96, initial_gain_psd); + PSD_report[10] = psd_report; + //Ch5 DC tone patch + psd_report = GetPSDData(pDM_Odm, 32, initial_gain_psd); + PSD_report[30] = psd_report; + +} + + +VOID +GoodChannelDecision( + IN PVOID pDM_VOID, + pu4Byte PSD_report, + pu1Byte PSD_bitmap, + u1Byte RSSI_BT, + pu1Byte PSD_bitmap_memory) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRXHP_T pRX_HP_Table = &pDM_Odm->DM_RXHP_Table; + //s4Byte TH1 = SSBT-0x15; // modify TH by Neil Chen + s4Byte TH1= RSSI_BT+0x14; + s4Byte TH2 = RSSI_BT+85; + //u2Byte TH3; +// s4Byte RegB34; + u1Byte bitmap, Smooth_size[3], Smooth_TH[3]; + //u1Byte psd_bit; + u4Byte i,n,j, byte_idx, bit_idx, good_cnt, good_cnt_smoothing, Smooth_Interval[3]; + int start_byte_idx,start_bit_idx,cur_byte_idx, cur_bit_idx,NOW_byte_idx ; + +// RegB34 = PHY_QueryBBReg(Adapter,0xB34, bMaskDWord)&0xFF; + + if((pDM_Odm->SupportICType == ODM_RTL8192C)||(pDM_Odm->SupportICType == ODM_RTL8192D)) + { + TH1 = RSSI_BT + 0x14; + } + + Smooth_size[0]=Smooth_Size_1; + Smooth_size[1]=Smooth_Size_2; + Smooth_size[2]=Smooth_Size_3; + Smooth_TH[0]=Smooth_TH_1; + Smooth_TH[1]=Smooth_TH_2; + Smooth_TH[2]=Smooth_TH_3; + Smooth_Interval[0]=16; + Smooth_Interval[1]=15; + Smooth_Interval[2]=13; + good_cnt = 0; + if(pDM_Odm->SupportICType==ODM_RTL8723A) + { + //2 Threshold + + if(RSSI_BT >=41) + TH1 = 113; + else if(RSSI_BT >=38) // >= -15dBm + TH1 = 105; //0x69 + else if((RSSI_BT >=33)&(RSSI_BT <38)) + TH1 = 99+(RSSI_BT-33); //0x63 + else if((RSSI_BT >=26)&(RSSI_BT<33)) + TH1 = 99-(33-RSSI_BT)+2; //0x5e + else if((RSSI_BT >=24)&(RSSI_BT<26)) + TH1 = 88-((RSSI_BT-24)*3); //0x58 + else if((RSSI_BT >=18)&(RSSI_BT<24)) + TH1 = 77+((RSSI_BT-18)*2); + else if((RSSI_BT >=14)&(RSSI_BT<18)) + TH1 = 63+((RSSI_BT-14)*2); + else if((RSSI_BT >=8)&(RSSI_BT<14)) + TH1 = 58+((RSSI_BT-8)*2); + else if((RSSI_BT >=3)&(RSSI_BT<8)) + TH1 = 52+(RSSI_BT-3); + else + TH1 = 51; + } + + for (i = 0; i< 10; i++) + PSD_bitmap[i] = 0; + + + // Add By Gary + for (i=0; i<80; i++) + pRX_HP_Table->PSD_bitmap_RXHP[i] = 0; + // End + + + + if(pDM_Odm->SupportICType==ODM_RTL8723A) + { + TH1 =TH1-SIR_STEP_SIZE; + } + while (good_cnt < PSD_CHMIN) + { + good_cnt = 0; + if(pDM_Odm->SupportICType==ODM_RTL8723A) + { + if(TH1 ==TH2) + break; + if((TH1+SIR_STEP_SIZE) < TH2) + TH1 += SIR_STEP_SIZE; + else + TH1 = TH2; + } + else + { + if(TH1==(RSSI_BT+0x1E)) + break; + if((TH1+2) < (RSSI_BT+0x1E)) + TH1+=3; + else + TH1 = RSSI_BT+0x1E; + + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD,DBG_LOUD,("PSD: decision threshold is: %d", TH1)); + + for (i = 0; i< 80; i++) + { + if((s4Byte)(PSD_report[i]) < TH1) + { + byte_idx = i / 8; + bit_idx = i -8*byte_idx; + bitmap = PSD_bitmap[byte_idx]; + PSD_bitmap[byte_idx] = bitmap | (u1Byte) (1 << bit_idx); + } + } + +#if DBG + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD: before smoothing\n")); + for(n=0;n<10;n++) + { + //DbgPrint("PSD_bitmap[%u]=%x\n", n, PSD_bitmap[n]); + for (i = 0; i<8; i++) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD_bitmap[%u] = %d\n", 2402+n*8+i, (PSD_bitmap[n]&BIT(i))>>i)); + } +#endif + + //1 Start of smoothing function + + for (j=0;j<3;j++) + { + start_byte_idx=0; + start_bit_idx=0; + for(n=0; n 7 ) + { + start_byte_idx= start_byte_idx+start_bit_idx/8; + start_bit_idx = start_bit_idx%8; + } + } + + ODM_RT_TRACE( pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD: after %u smoothing", j+1)); + for(n=0;n<10;n++) + { + for (i = 0; i<8; i++) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD_bitmap[%u] = %d\n", 2402+n*8+i, (PSD_bitmap[n]&BIT(i))>>i)); + + if ( ((PSD_bitmap[n]&BIT(i))>>i) ==1) //----- Add By Gary + { + pRX_HP_Table->PSD_bitmap_RXHP[8*n+i] = 1; + } // ------end by Gary + } + } + + } + + + good_cnt = 0; + for ( i = 0; i < 10; i++) + { + for (n = 0; n < 8; n++) + if((PSD_bitmap[i]& BIT(n)) != 0) + good_cnt++; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, ODM_COMP_PSD,("PSD: good channel cnt = %u",good_cnt)); + } + + //RT_TRACE(ODM_COMP_PSD, DBG_LOUD,("PSD: SSBT=%d, TH2=%d, TH1=%d",SSBT,TH2,TH1)); + for (i = 0; i <10; i++) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD: PSD_bitmap[%u]=%x",i,PSD_bitmap[i])); +/* + //Update bitmap memory + for(i = 0; i < 80; i++) + { + byte_idx = i / 8; + bit_idx = i -8*byte_idx; + psd_bit = (PSD_bitmap[byte_idx] & BIT(bit_idx)) >> bit_idx; + bitmap = PSD_bitmap_memory[i]; + PSD_bitmap_memory[i] = (bitmap << 1) |psd_bit; + } +*/ +} + + + +VOID +odm_PSD_Monitor( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + unsigned int pts, start_point, stop_point; + u1Byte initial_gain ; + static u1Byte PSD_bitmap_memory[80], init_memory = 0; + static u1Byte psd_cnt=0; + static u4Byte PSD_report[80], PSD_report_tmp; + static u8Byte lastTxOkCnt=0, lastRxOkCnt=0; + u1Byte H2C_PSD_DATA[5]={0,0,0,0,0}; + static u1Byte H2C_PSD_DATA_last[5] ={0,0,0,0,0}; + u1Byte idx[20]={96,99,102,106,109,112,115,118,122,125, + 0,3,6,10,13,16,19,22,26,29}; + u1Byte n, i, channel, BBReset,tone_idx; + u1Byte PSD_bitmap[10], SSBT=0,initial_gain_psd=0, RSSI_BT=0, initialGainUpper; + s4Byte PSD_skip_start, PSD_skip_stop; + u4Byte CurrentChannel, RXIQI, RxIdleLowPwr, wlan_channel; + u4Byte ReScan, Interval, Is40MHz; + u8Byte curTxOkCnt, curRxOkCnt; + int cur_byte_idx, cur_bit_idx; + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + + if(*pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("pbDriverIsGoingToPnpSetPowerSleep!!!!!!!!!!!!!!!\n")); + return; + } + + + if( (*(pDM_Odm->pbScanInProcess)) || + pDM_Odm->bLinkInProcess) + { + if((pDM_Odm->SupportICType==ODM_RTL8723A)&(pDM_Odm->SupportInterface==ODM_ITRF_PCIE)) + { + ODM_SetTimer( pDM_Odm, &pDM_Odm->PSDTimer, 1500); //ms + //psd_cnt=0; + } + return; + } + + if(pDM_Odm->bBtHsOperation) + { + ReScan = 1; + Interval = SCAN_INTERVAL; + } + else + { + ReScan = PSD_RESCAN; + Interval = SCAN_INTERVAL; + } + + //1 Initialization + if(init_memory == 0) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("Init memory\n")); + for(i = 0; i < 80; i++) + PSD_bitmap_memory[i] = 0xFF; // channel is always good + init_memory = 1; + } + if(psd_cnt == 0) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("Enter dm_PSD_Monitor\n")); + for(i = 0; i < 80; i++) + PSD_report[i] = 0; + } + + //1 Backup Current Settings + CurrentChannel = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask); +/* + if(pDM_Odm->SupportICType==ODM_RTL8192D) + { + //2 Record Current synthesizer parameters based on current channel + if((*pDM_Odm->MacPhyMode92D == SINGLEMAC_SINGLEPHY)||(*pDM_Odm->MacPhyMode92D == DUALMAC_SINGLEPHY)) + { + SYN_RF25 = ODM_GetRFReg(Adapter, ODM_RF_PATH_B, 0x25, bMaskDWord); + SYN_RF26 = ODM_GetRFReg(Adapter, ODM_RF_PATH_B, 0x26, bMaskDWord); + SYN_RF27 = ODM_GetRFReg(Adapter, ODM_RF_PATH_B, 0x27, bMaskDWord); + SYN_RF2B = ODM_GetRFReg(Adapter, ODM_RF_PATH_B, 0x2B, bMaskDWord); + SYN_RF2C = ODM_GetRFReg(Adapter, ODM_RF_PATH_B, 0x2C, bMaskDWord); + } + else // DualMAC_DualPHY 2G + { + SYN_RF25 = ODM_GetRFReg(Adapter, ODM_RF_PATH_A, 0x25, bMaskDWord); + SYN_RF26 = ODM_GetRFReg(Adapter, ODM_RF_PATH_A, 0x26, bMaskDWord); + SYN_RF27 = ODM_GetRFReg(Adapter, ODM_RF_PATH_A, 0x27, bMaskDWord); + SYN_RF2B = ODM_GetRFReg(Adapter, ODM_RF_PATH_A, 0x2B, bMaskDWord); + SYN_RF2C = ODM_GetRFReg(Adapter, ODM_RF_PATH_A, 0x2C, bMaskDWord); + } + } +*/ + //RXIQI = PHY_QueryBBReg(Adapter, 0xC14, bMaskDWord); + RXIQI = ODM_GetBBReg(pDM_Odm, 0xC14, bMaskDWord); + + //RxIdleLowPwr = (PHY_QueryBBReg(Adapter, 0x818, bMaskDWord)&BIT28)>>28; + RxIdleLowPwr = (ODM_GetBBReg(pDM_Odm, 0x818, bMaskDWord)&BIT28)>>28; + + //2??? + if(CHNL_RUN_ABOVE_40MHZ(pMgntInfo)) + Is40MHz = TRUE; + else + Is40MHz = FALSE; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PSD, DBG_LOUD,("PSD Scan Start\n")); + //1 Turn off CCK + //PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT24, 0); + ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 0); + //1 Turn off TX + //Pause TX Queue + //PlatformEFIOWrite1Byte(Adapter, REG_TXPAUSE, 0xFF); + ODM_Write1Byte(pDM_Odm,REG_TXPAUSE, 0xFF); + + //Force RX to stop TX immediately + //PHY_SetRFReg(Adapter, ODM_RF_PATH_A, RF_AC, bRFRegOffsetMask, 0x32E13); + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bRFRegOffsetMask, 0x32E13); + //1 Turn off RX + //Rx AGC off RegC70[0]=0, RegC7C[20]=0 + //PHY_SetBBReg(Adapter, 0xC70, BIT0, 0); + //PHY_SetBBReg(Adapter, 0xC7C, BIT20, 0); + + ODM_SetBBReg(pDM_Odm, 0xC70, BIT0, 0); + ODM_SetBBReg(pDM_Odm, 0xC7C, BIT20, 0); + + + //Turn off CCA + //PHY_SetBBReg(Adapter, 0xC14, bMaskDWord, 0x0); + ODM_SetBBReg(pDM_Odm, 0xC14, bMaskDWord, 0x0); + + //BB Reset + //BBReset = PlatformEFIORead1Byte(Adapter, 0x02); + BBReset = ODM_Read1Byte(pDM_Odm, 0x02); + + //PlatformEFIOWrite1Byte(Adapter, 0x02, BBReset&(~BIT0)); + //PlatformEFIOWrite1Byte(Adapter, 0x02, BBReset|BIT0); + ODM_SetBBReg(pDM_Odm, 0x87C, BIT31, 1); //clock gated to prevent from AGC table mess + ODM_Write1Byte(pDM_Odm, 0x02, BBReset&(~BIT0)); + ODM_Write1Byte(pDM_Odm, 0x02, BBReset|BIT0); + ODM_SetBBReg(pDM_Odm, 0x87C, BIT31, 0); + + //1 Leave RX idle low power + //PHY_SetBBReg(Adapter, 0x818, BIT28, 0x0); + + ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 0x0); + //1 Fix initial gain + //if (IS_HARDWARE_TYPE_8723AE(Adapter)) + //RSSI_BT = pHalData->RSSI_BT; + //else if((IS_HARDWARE_TYPE_8192C(Adapter))||(IS_HARDWARE_TYPE_8192D(Adapter))) // Add by Gary + // RSSI_BT = RSSI_BT_new; + + if((pDM_Odm->SupportICType==ODM_RTL8723A)&(pDM_Odm->SupportInterface==ODM_ITRF_PCIE)) + RSSI_BT=pDM_Odm->RSSI_BT; //need to check C2H to pDM_Odm RSSI BT + + if(RSSI_BT>=47) + RSSI_BT=47; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD: RSSI_BT= %d\n", RSSI_BT)); + + if(pDM_Odm->SupportICType==ODM_RTL8723A) + { + //Neil add--2011--10--12 + //2 Initial Gain index + if(RSSI_BT >=35) // >= -15dBm + initial_gain_psd = RSSI_BT*2; + else if((RSSI_BT >=33)&(RSSI_BT<35)) + initial_gain_psd = RSSI_BT*2+6; + else if((RSSI_BT >=24)&(RSSI_BT<33)) + initial_gain_psd = 70-(33-RSSI_BT); + else if((RSSI_BT >=19)&(RSSI_BT<24)) + initial_gain_psd = 64-((24-RSSI_BT)*4); + else if((RSSI_BT >=14)&(RSSI_BT<19)) + initial_gain_psd = 44-((18-RSSI_BT)*2); + else if((RSSI_BT >=8)&(RSSI_BT<14)) + initial_gain_psd = 35-(14-RSSI_BT); + else + initial_gain_psd = 0x1B; + } + else + { + + //need to do + initial_gain_psd = pDM_Odm->RSSI_Min; // PSD report based on RSSI + //} + } + //if(RSSI_BT<0x17) + // RSSI_BT +=3; + //DbgPrint("PSD: RSSI_BT= %d\n", RSSI_BT); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD: RSSI_BT= %d\n", RSSI_BT)); + + //initialGainUpper = 0x5E; //Modify by neil chen + + if(pDM_Odm->bUserAssignLevel) + { + pDM_Odm->bUserAssignLevel = FALSE; + initialGainUpper = 0x7f; + } + else + { + initialGainUpper = 0x5E; + } + + /* + if (initial_gain_psd < 0x1a) + initial_gain_psd = 0x1a; + if (initial_gain_psd > initialGainUpper) + initial_gain_psd = initialGainUpper; + */ + + //if(pDM_Odm->SupportICType==ODM_RTL8723A) + SSBT = RSSI_BT * 2 +0x3E; + + + //if(IS_HARDWARE_TYPE_8723AE(Adapter)) + // SSBT = RSSI_BT * 2 +0x3E; + //else if((IS_HARDWARE_TYPE_8192C(Adapter))||(IS_HARDWARE_TYPE_8192D(Adapter))) // Add by Gary + //{ + // RSSI_BT = initial_gain_psd; + // SSBT = RSSI_BT; + //} + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD: SSBT= %d\n", SSBT)); + ODM_RT_TRACE( pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD: initial gain= 0x%x\n", initial_gain_psd)); + //DbgPrint("PSD: SSBT= %d", SSBT); + //need to do + pDM_Odm->bDMInitialGainEnable = FALSE; + initial_gain =(u1Byte) (ODM_GetBBReg(pDM_Odm, 0xc50, bMaskDWord) & 0x7F); + + // make sure the initial gain is under the correct range. + //initial_gain_psd &= 0x7f; + ODM_Write_DIG(pDM_Odm, initial_gain_psd); + //1 Turn off 3-wire + ODM_SetBBReg(pDM_Odm, 0x88c, BIT20|BIT21|BIT22|BIT23, 0xF); + + //pts value = 128, 256, 512, 1024 + pts = 128; + + if(pts == 128) + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x0); + start_point = 64; + stop_point = 192; + } + else if(pts == 256) + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x1); + start_point = 128; + stop_point = 384; + } + else if(pts == 512) + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x2); + start_point = 256; + stop_point = 768; + } + else + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x3); + start_point = 512; + stop_point = 1536; + } + + +//3 Skip WLAN channels if WLAN busy + + curTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast) - lastTxOkCnt; + curRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast) - lastRxOkCnt; + lastTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast); + lastRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast); + + PSD_skip_start=80; + PSD_skip_stop = 0; + wlan_channel = CurrentChannel & 0x0f; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD,DBG_LOUD,("PSD: current channel: %x, BW:%d \n", wlan_channel, Is40MHz)); + if(pDM_Odm->SupportICType==ODM_RTL8723A) + { + if(pDM_Odm->bBtHsOperation) + { + if(pDM_Odm->bLinked) + { + if(Is40MHz) + { + PSD_skip_start = ((wlan_channel-1)*5 -Is40MHz*10)-2; // Modify by Neil to add 10 chs to mask + PSD_skip_stop = (PSD_skip_start + (1+Is40MHz)*20)+4; + } + else + { + PSD_skip_start = ((wlan_channel-1)*5 -Is40MHz*10)-10; // Modify by Neil to add 10 chs to mask + PSD_skip_stop = (PSD_skip_start + (1+Is40MHz)*20)+18; + } + } + else + { + // mask for 40MHz + PSD_skip_start = ((wlan_channel-1)*5 -Is40MHz*10)-2; // Modify by Neil to add 10 chs to mask + PSD_skip_stop = (PSD_skip_start + (1+Is40MHz)*20)+4; + } + if(PSD_skip_start < 0) + PSD_skip_start = 0; + if(PSD_skip_stop >80) + PSD_skip_stop = 80; + } + else + { + if((curRxOkCnt+curTxOkCnt) > 5) + { + if(Is40MHz) + { + PSD_skip_start = ((wlan_channel-1)*5 -Is40MHz*10)-2; // Modify by Neil to add 10 chs to mask + PSD_skip_stop = (PSD_skip_start + (1+Is40MHz)*20)+4; + } + else + { + PSD_skip_start = ((wlan_channel-1)*5 -Is40MHz*10)-10; // Modify by Neil to add 10 chs to mask + PSD_skip_stop = (PSD_skip_start + (1+Is40MHz)*20)+18; + } + + if(PSD_skip_start < 0) + PSD_skip_start = 0; + if(PSD_skip_stop >80) + PSD_skip_stop = 80; + } + } + } +#if 0 + else + { + if((curRxOkCnt+curTxOkCnt) > 1000) + { + PSD_skip_start = (wlan_channel-1)*5 -Is40MHz*10; + PSD_skip_stop = PSD_skip_start + (1+Is40MHz)*20; + } + } +#endif //Reove RXHP Issue + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD,DBG_LOUD,("PSD: Skip tone from %d to %d \n", PSD_skip_start, PSD_skip_stop)); + + for (n=0;n<80;n++) + { + if((n%20)==0) + { + channel = (n/20)*4 + 1; + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, channel); + } + tone_idx = n%20; + if ((n>=PSD_skip_start) && (n PSD_report[n]) + PSD_report[n] = PSD_report_tmp; + + } + } + + PatchDCTone(pDM_Odm, PSD_report, initial_gain_psd); + + //----end + //1 Turn on RX + //Rx AGC on + ODM_SetBBReg(pDM_Odm, 0xC70, BIT0, 1); + ODM_SetBBReg(pDM_Odm, 0xC7C, BIT20, 1); + //CCK on + ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 1); + //1 Turn on TX + //Resume TX Queue + + ODM_Write1Byte(pDM_Odm,REG_TXPAUSE, 0x00); + //Turn on 3-wire + ODM_SetBBReg(pDM_Odm, 0x88c, BIT20|BIT21|BIT22|BIT23, 0x0); + //1 Restore Current Settings + //Resume DIG + pDM_Odm->bDMInitialGainEnable = TRUE; + + ODM_Write_DIG(pDM_Odm, initial_gain); + + // restore originl center frequency + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); + + //Turn on CCA + ODM_SetBBReg(pDM_Odm, 0xC14, bMaskDWord, RXIQI); + //Restore RX idle low power + if(RxIdleLowPwr == TRUE) + ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 1); + + psd_cnt++; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD:psd_cnt = %d \n",psd_cnt)); + if (psd_cnt < ReScan) + ODM_SetTimer(pDM_Odm, &pDM_Odm->PSDTimer, Interval); + else + { + psd_cnt = 0; + for(i=0;i<80;i++) + //DbgPrint("psd_report[%d]= %d \n", 2402+i, PSD_report[i]); + RT_TRACE( ODM_COMP_PSD, DBG_LOUD,("psd_report[%d]= %d \n", 2402+i, PSD_report[i])); + + + GoodChannelDecision(pDM_Odm, PSD_report, PSD_bitmap,RSSI_BT, PSD_bitmap_memory); + + if(pDM_Odm->SupportICType==ODM_RTL8723A) + { + cur_byte_idx=0; + cur_bit_idx=0; + + //2 Restore H2C PSD Data to Last Data + H2C_PSD_DATA_last[0] = H2C_PSD_DATA[0]; + H2C_PSD_DATA_last[1] = H2C_PSD_DATA[1]; + H2C_PSD_DATA_last[2] = H2C_PSD_DATA[2]; + H2C_PSD_DATA_last[3] = H2C_PSD_DATA[3]; + H2C_PSD_DATA_last[4] = H2C_PSD_DATA[4]; + + + //2 Translate 80bit channel map to 40bit channel + for ( i=0;i<5;i++) + { + for(n=0;n<8;n++) + { + cur_byte_idx = i*2 + n/4; + cur_bit_idx = (n%4)*2; + if ( ((PSD_bitmap[cur_byte_idx]& BIT(cur_bit_idx)) != 0) && ((PSD_bitmap[cur_byte_idx]& BIT(cur_bit_idx+1)) != 0)) + H2C_PSD_DATA[i] = H2C_PSD_DATA[i] | (u1Byte) (1 << n); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("H2C_PSD_DATA[%d]=0x%x\n" ,i, H2C_PSD_DATA[i])); + } + + //3 To Compare the difference + for ( i=0;i<5;i++) + { + if(H2C_PSD_DATA[i] !=H2C_PSD_DATA_last[i]) + { + FW_FillH2CCmd(Adapter, H2C_92C_PSD_RESULT, 5, H2C_PSD_DATA); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PSD, DBG_LOUD,("Need to Update the AFH Map \n")); + break; + } + else + { + if(i==5) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("Not need to Update\n")); + } + } + if(pDM_Odm->bBtHsOperation) + { + ODM_SetTimer(pDM_Odm, &pDM_Odm->PSDTimer, 10000); + ODM_RT_TRACE( pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("Leave dm_PSD_Monitor\n")); + } + else + { + ODM_SetTimer(pDM_Odm, &pDM_Odm->PSDTimer, 1500); + ODM_RT_TRACE( pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("Leave dm_PSD_Monitor\n")); + } + } + } +} +/* +//Neil for Get BT RSSI +// Be Triggered by BT C2H CMD +VOID +ODM_PSDGetRSSI( + IN u1Byte RSSI_BT) +{ + + +} + +*/ + +VOID +ODM_PSDMonitor( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + //if(IS_HARDWARE_TYPE_8723AE(Adapter)) + + if(pDM_Odm->SupportICType == ODM_RTL8723A) //may need to add other IC type + { + if(pDM_Odm->SupportInterface==ODM_ITRF_PCIE) + { + if(!pDM_Odm->bBtEnabled) //need to check upper layer connection + { + pDM_Odm->bPSDactive=FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD, ("odm_PSDMonitor, return for BT is disabled!!!\n")); + return; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD, ("odm_PSDMonitor\n")); + //{ + pDM_Odm->bPSDinProcess = TRUE; + pDM_Odm->bPSDactive=TRUE; + odm_PSD_Monitor(pDM_Odm); + pDM_Odm->bPSDinProcess = FALSE; + } + } + +} +VOID +odm_PSDMonitorCallback( + PRT_TIMER pTimer +) +{ + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + PlatformScheduleWorkItem(&pHalData->PSDMonitorWorkitem); +} + +VOID +odm_PSDMonitorWorkItemCallback( + IN PVOID pContext + ) +{ + PADAPTER Adapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + ODM_PSDMonitor(pDM_Odm); +} + + + //cosa debug tool need to modify + +VOID +ODM_PSDDbgControl( + IN PADAPTER Adapter, + IN u4Byte mode, + IN u4Byte btRssi + ) +{ +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD, (" Monitor mode=%d, btRssi=%d\n", mode, btRssi)); + if(mode) + { + pDM_Odm->RSSI_BT = (u1Byte)btRssi; + pDM_Odm->bUserAssignLevel = TRUE; + ODM_SetTimer( pDM_Odm, &pDM_Odm->PSDTimer, 0); //ms + } + else + { + ODM_CancelTimer(pDM_Odm, &pDM_Odm->PSDTimer); + } +#endif +} + + +//#if(DEV_BUS_TYPE == RT_PCI_INTERFACE)|(DEV_BUS_TYPE == RT_USB_INTERFACE) + +void odm_RXHPInit( + IN PVOID pDM_VOID) +{ +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)|(DEV_BUS_TYPE == RT_USB_INTERFACE) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRXHP_T pRX_HP_Table = &pDM_Odm->DM_RXHP_Table; + u1Byte index; + + pRX_HP_Table->RXHP_enable = TRUE; + pRX_HP_Table->RXHP_flag = 0; + pRX_HP_Table->PSD_func_trigger = 0; + pRX_HP_Table->Pre_IGI = 0x20; + pRX_HP_Table->Cur_IGI = 0x20; + pRX_HP_Table->Cur_pw_th = pw_th_10dB; + pRX_HP_Table->Pre_pw_th = pw_th_10dB; + for(index=0; index<80; index++) + pRX_HP_Table->PSD_bitmap_RXHP[index] = 1; + +#if(DEV_BUS_TYPE == RT_USB_INTERFACE) + pRX_HP_Table->TP_Mode = Idle_Mode; +#endif +#endif +} + +VOID +odm_PSD_RXHP( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRXHP_T pRX_HP_Table = &pDM_Odm->DM_RXHP_Table; + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + unsigned int pts, start_point, stop_point, initial_gain ; + static u1Byte PSD_bitmap_memory[80], init_memory = 0; + static u1Byte psd_cnt=0; + static u4Byte PSD_report[80], PSD_report_tmp; + static u8Byte lastTxOkCnt=0, lastRxOkCnt=0; + u1Byte idx[20]={96,99,102,106,109,112,115,118,122,125, + 0,3,6,10,13,16,19,22,26,29}; + u1Byte n, i, channel, BBReset,tone_idx; + u1Byte PSD_bitmap[10]/*, SSBT=0*/,initial_gain_psd=0, RSSI_BT=0, initialGainUpper; + s4Byte PSD_skip_start, PSD_skip_stop; + u4Byte CurrentChannel, RXIQI, RxIdleLowPwr, wlan_channel; + u4Byte ReScan, Interval, Is40MHz; + u8Byte curTxOkCnt, curRxOkCnt; + //--------------2G band synthesizer for 92D switch RF channel using----------------- + u1Byte group_idx=0; + u4Byte SYN_RF25=0, SYN_RF26=0, SYN_RF27=0, SYN_RF2B=0, SYN_RF2C=0; + u4Byte SYN[5] = {0x25, 0x26, 0x27, 0x2B, 0x2C}; // synthesizer RF register for 2G channel + u4Byte SYN_group[3][5] = {{0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840}, // For CH1,2,4,9,10.11.12 {0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840} + {0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840}, // For CH3,13,14 + {0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41}}; // For Ch5,6,7,8 + //--------------------- Add by Gary for Debug setting ---------------------- + u1Byte RSSI_BT_new = (u1Byte) ODM_GetBBReg(pDM_Odm, 0xB9C, 0xFF); + u1Byte rssi_ctrl = (u1Byte) ODM_GetBBReg(pDM_Odm, 0xB38, 0xFF); + //--------------------------------------------------------------------- + + if(pMgntInfo->bScanInProgress) + { + return; + } + + ReScan = PSD_RESCAN; + Interval = SCAN_INTERVAL; + + + //1 Initialization + if(init_memory == 0) + { + RT_TRACE( ODM_COMP_PSD, DBG_LOUD,("Init memory\n")); + for(i = 0; i < 80; i++) + PSD_bitmap_memory[i] = 0xFF; // channel is always good + init_memory = 1; + } + if(psd_cnt == 0) + { + RT_TRACE(ODM_COMP_PSD, DBG_LOUD,("Enter dm_PSD_Monitor\n")); + for(i = 0; i < 80; i++) + PSD_report[i] = 0; + } + + //1 Backup Current Settings + CurrentChannel = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask); + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + //2 Record Current synthesizer parameters based on current channel + if((*(pDM_Odm->pMacPhyMode)==ODM_SMSP)||(*(pDM_Odm->pMacPhyMode)==ODM_DMSP)) + { + SYN_RF25 = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x25, bMaskDWord); + SYN_RF26 = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x26, bMaskDWord); + SYN_RF27 = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x27, bMaskDWord); + SYN_RF2B = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x2B, bMaskDWord); + SYN_RF2C = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x2C, bMaskDWord); + } + else // DualMAC_DualPHY 2G + { + SYN_RF25 = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x25, bMaskDWord); + SYN_RF26 = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x26, bMaskDWord); + SYN_RF27 = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x27, bMaskDWord); + SYN_RF2B = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x2B, bMaskDWord); + SYN_RF2C = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x2C, bMaskDWord); + } + } + RXIQI = ODM_GetBBReg(pDM_Odm, 0xC14, bMaskDWord); + RxIdleLowPwr = (ODM_GetBBReg(pDM_Odm, 0x818, bMaskDWord)&BIT28)>>28; + Is40MHz = *(pDM_Odm->pBandWidth); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PSD, DBG_LOUD,("PSD Scan Start\n")); + //1 Turn off CCK + ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 0); + //1 Turn off TX + //Pause TX Queue + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0xFF); + //Force RX to stop TX immediately + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bRFRegOffsetMask, 0x32E13); + //1 Turn off RX + //Rx AGC off RegC70[0]=0, RegC7C[20]=0 + ODM_SetBBReg(pDM_Odm, 0xC70, BIT0, 0); + ODM_SetBBReg(pDM_Odm, 0xC7C, BIT20, 0); + //Turn off CCA + ODM_SetBBReg(pDM_Odm, 0xC14, bMaskDWord, 0x0); + //BB Reset + ODM_SetBBReg(pDM_Odm, 0x87C, BIT31, 1); //clock gated to prevent from AGC table mess + BBReset = ODM_Read1Byte(pDM_Odm, 0x02); + ODM_Write1Byte(pDM_Odm, 0x02, BBReset&(~BIT0)); + ODM_Write1Byte(pDM_Odm, 0x02, BBReset|BIT0); + ODM_SetBBReg(pDM_Odm, 0x87C, BIT31, 0); + //1 Leave RX idle low power + ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 0x0); + //1 Fix initial gain + RSSI_BT = RSSI_BT_new; + RT_TRACE(ODM_COMP_PSD, DBG_LOUD,("PSD: RSSI_BT= %d\n", RSSI_BT)); + + if(rssi_ctrl == 1) // just for debug!! + initial_gain_psd = RSSI_BT_new; + else + initial_gain_psd = pDM_Odm->RSSI_Min; // PSD report based on RSSI + + RT_TRACE(ODM_COMP_PSD, DBG_LOUD,("PSD: RSSI_BT= %d\n", RSSI_BT)); + + initialGainUpper = 0x54; + + RSSI_BT = initial_gain_psd; + //SSBT = RSSI_BT; + + //RT_TRACE( ODM_COMP_PSD, DBG_LOUD,("PSD: SSBT= %d\n", SSBT)); + RT_TRACE( ODM_COMP_PSD, DBG_LOUD,("PSD: initial gain= 0x%x\n", initial_gain_psd)); + + pDM_Odm->bDMInitialGainEnable = FALSE; + initial_gain = ODM_GetBBReg(pDM_Odm, 0xc50, bMaskDWord) & 0x7F; + //ODM_SetBBReg(pDM_Odm, 0xc50, 0x7F, initial_gain_psd); + ODM_Write_DIG(pDM_Odm, initial_gain_psd); + //1 Turn off 3-wire + ODM_SetBBReg(pDM_Odm, 0x88c, BIT20|BIT21|BIT22|BIT23, 0xF); + + //pts value = 128, 256, 512, 1024 + pts = 128; + + if(pts == 128) + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x0); + start_point = 64; + stop_point = 192; + } + else if(pts == 256) + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x1); + start_point = 128; + stop_point = 384; + } + else if(pts == 512) + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x2); + start_point = 256; + stop_point = 768; + } + else + { + ODM_SetBBReg(pDM_Odm, 0x808, BIT14|BIT15, 0x3); + start_point = 512; + stop_point = 1536; + } + + +//3 Skip WLAN channels if WLAN busy + curTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast) - lastTxOkCnt; + curRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast) - lastRxOkCnt; + lastTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast); + lastRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast); + + PSD_skip_start=80; + PSD_skip_stop = 0; + wlan_channel = CurrentChannel & 0x0f; + + RT_TRACE(ODM_COMP_PSD,DBG_LOUD,("PSD: current channel: %x, BW:%d \n", wlan_channel, Is40MHz)); + + if((curRxOkCnt+curTxOkCnt) > 1000) + { + PSD_skip_start = (wlan_channel-1)*5 -Is40MHz*10; + PSD_skip_stop = PSD_skip_start + (1+Is40MHz)*20; + } + + RT_TRACE(ODM_COMP_PSD,DBG_LOUD,("PSD: Skip tone from %d to %d \n", PSD_skip_start, PSD_skip_stop)); + + for (n=0;n<80;n++) + { + if((n%20)==0) + { + channel = (n/20)*4 + 1; + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + switch(channel) + { + case 1: + case 9: + group_idx = 0; + break; + case 5: + group_idx = 2; + break; + case 13: + group_idx = 1; + break; + } + if((*(pDM_Odm->pMacPhyMode)==ODM_SMSP)||(*(pDM_Odm->pMacPhyMode)==ODM_DMSP)) + { + for(i = 0; i < SYN_Length; i++) + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, SYN[i], bMaskDWord, SYN_group[group_idx][i]); + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, channel); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_CHNLBW, 0x3FF, channel); + } + else // DualMAC_DualPHY 2G + { + for(i = 0; i < SYN_Length; i++) + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, SYN[i], bMaskDWord, SYN_group[group_idx][i]); + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, channel); + } + } + else + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, channel); + } + tone_idx = n%20; + if ((n>=PSD_skip_start) && (n PSD_report[n]) + PSD_report[n] = PSD_report_tmp; + + } + } + + PatchDCTone(pDM_Odm, PSD_report, initial_gain_psd); + + //----end + //1 Turn on RX + //Rx AGC on + ODM_SetBBReg(pDM_Odm, 0xC70, BIT0, 1); + ODM_SetBBReg(pDM_Odm, 0xC7C, BIT20, 1); + //CCK on + ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 1); + //1 Turn on TX + //Resume TX Queue + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0x00); + //Turn on 3-wire + ODM_SetBBReg(pDM_Odm, 0x88c, BIT20|BIT21|BIT22|BIT23, 0x0); + //1 Restore Current Settings + //Resume DIG + pDM_Odm->bDMInitialGainEnable= TRUE; + //ODM_SetBBReg(pDM_Odm, 0xc50, 0x7F, initial_gain); + ODM_Write_DIG(pDM_Odm,(u1Byte) initial_gain); + // restore originl center frequency + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + if((*(pDM_Odm->pMacPhyMode)==ODM_SMSP)||(*(pDM_Odm->pMacPhyMode)==ODM_DMSP)) + { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_CHNLBW, bMaskDWord, CurrentChannel); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x25, bMaskDWord, SYN_RF25); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x26, bMaskDWord, SYN_RF26); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x27, bMaskDWord, SYN_RF27); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x2B, bMaskDWord, SYN_RF2B); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x2C, bMaskDWord, SYN_RF2C); + } + else // DualMAC_DualPHY + { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x25, bMaskDWord, SYN_RF25); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x26, bMaskDWord, SYN_RF26); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x27, bMaskDWord, SYN_RF27); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x2B, bMaskDWord, SYN_RF2B); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x2C, bMaskDWord, SYN_RF2C); + } + } + //Turn on CCA + ODM_SetBBReg(pDM_Odm, 0xC14, bMaskDWord, RXIQI); + //Restore RX idle low power + if(RxIdleLowPwr == TRUE) + ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 1); + + psd_cnt++; + //gPrint("psd cnt=%d\n", psd_cnt); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PSD, DBG_LOUD,("PSD:psd_cnt = %d \n",psd_cnt)); + if (psd_cnt < ReScan) + { + ODM_SetTimer(pDM_Odm, &pRX_HP_Table->PSDTimer, Interval); //ms + } + else + { + psd_cnt = 0; + for(i=0;i<80;i++) + RT_TRACE( ODM_COMP_PSD, DBG_LOUD,("psd_report[%d]= %d \n", 2402+i, PSD_report[i])); + //DbgPrint("psd_report[%d]= %d \n", 2402+i, PSD_report[i]); + + GoodChannelDecision(pDM_Odm, PSD_report, PSD_bitmap,RSSI_BT, PSD_bitmap_memory); + + } +} + +void odm_Write_RXHP( + IN PVOID pDM_VOID) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRXHP_T pRX_HP_Table = &pDM_Odm->DM_RXHP_Table; + u4Byte currentIGI; + + if(pRX_HP_Table->Cur_IGI != pRX_HP_Table->Pre_IGI) + { + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0, pRX_HP_Table->Cur_IGI); + ODM_SetBBReg(pDM_Odm, rOFDM0_XBAGCCore1, bMaskByte0, pRX_HP_Table->Cur_IGI); + } + + if(pRX_HP_Table->Cur_pw_th != pRX_HP_Table->Pre_pw_th) +{ + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore2, BIT8|BIT9, pRX_HP_Table->Cur_pw_th); // RegC54[9:8]=2'b11: AGC Flow 3 + } + + if(pRX_HP_Table->RXHP_flag == 0) + { + pRX_HP_Table->Cur_IGI = 0x20; + } + else + { + currentIGI = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0); + if(currentIGI<0x50) + { + ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0, pRX_HP_Table->Cur_IGI); + ODM_SetBBReg(pDM_Odm, rOFDM0_XBAGCCore1, bMaskByte0, pRX_HP_Table->Cur_IGI); + } + } + pRX_HP_Table->Pre_IGI = pRX_HP_Table->Cur_IGI; + pRX_HP_Table->Pre_pw_th = pRX_HP_Table->Cur_pw_th; + +} + + +void odm_RXHP( + IN PVOID pDM_VOID) +{ +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN)) +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) | (DEV_BUS_TYPE == RT_USB_INTERFACE) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + pRXHP_T pRX_HP_Table = &pDM_Odm->DM_RXHP_Table; + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm , PHYDM_FALSEALMCNT); + + u1Byte i, j, sum; + u1Byte Is40MHz; + s1Byte Intf_diff_idx, MIN_Intf_diff_idx = 16; + s4Byte cur_channel; + u1Byte ch_map_intf_5M[17] = {0}; + static u4Byte FA_TH = 0; + static u1Byte psd_intf_flag = 0; + static s4Byte curRssi = 0; + static s4Byte preRssi = 0; + static u1Byte PSDTriggerCnt = 1; + + u1Byte RX_HP_enable = (u1Byte)(ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore2, bMaskDWord)>>31); // for debug!! + +#if(DEV_BUS_TYPE == RT_USB_INTERFACE) + static s8Byte lastTxOkCnt = 0, lastRxOkCnt = 0; + s8Byte curTxOkCnt, curRxOkCnt; + s8Byte curTPOkCnt; + s8Byte TP_Acc3, TP_Acc5; + static s8Byte TP_Buff[5] = {0}; + static u1Byte pre_state = 0, pre_state_flag = 0; + static u1Byte Intf_HighTP_flag = 0, De_counter = 16; + static u1Byte TP_Degrade_flag = 0; +#endif + static u1Byte LatchCnt = 0; + + if(pDM_Odm->SupportICType & (ODM_RTL8723A|ODM_RTL8188E)) + return; + //AGC RX High Power Mode is only applied on 2G band in 92D!!! + if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + if(*(pDM_Odm->pBandType) != ODM_BAND_2_4G) + return; + } + + if(!(pDM_Odm->SupportAbility & ODM_BB_RXHP)) + return; + + + //RX HP ON/OFF + if(RX_HP_enable == 1) + pRX_HP_Table->RXHP_enable = FALSE; + else + pRX_HP_Table->RXHP_enable = TRUE; + + if(pRX_HP_Table->RXHP_enable == FALSE) + { + if(pRX_HP_Table->RXHP_flag == 1) + { + pRX_HP_Table->RXHP_flag = 0; + psd_intf_flag = 0; + } + return; + } + +#if(DEV_BUS_TYPE == RT_USB_INTERFACE) + //2 Record current TP for USB interface + curTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast)-lastTxOkCnt; + curRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast)-lastRxOkCnt; + lastTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast); + lastRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast); + + curTPOkCnt = curTxOkCnt+curRxOkCnt; + TP_Buff[0] = curTPOkCnt; // current TP + TP_Acc3 = PlatformDivision64((TP_Buff[1]+TP_Buff[2]+TP_Buff[3]), 3); + TP_Acc5 = PlatformDivision64((TP_Buff[0]+TP_Buff[1]+TP_Buff[2]+TP_Buff[3]+TP_Buff[4]), 5); + + if(TP_Acc5 < 1000) + pRX_HP_Table->TP_Mode = Idle_Mode; + else if((1000 < TP_Acc5)&&(TP_Acc5 < 3750000)) + pRX_HP_Table->TP_Mode = Low_TP_Mode; + else + pRX_HP_Table->TP_Mode = High_TP_Mode; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RX HP TP Mode = %d\n", pRX_HP_Table->TP_Mode)); + // Since TP result would be sampled every 2 sec, it needs to delay 4sec to wait PSD processing. + // When LatchCnt = 0, we would Get PSD result. + if(TP_Degrade_flag == 1) + { + LatchCnt--; + if(LatchCnt == 0) + { + TP_Degrade_flag = 0; + } + } + // When PSD function triggered by TP degrade 20%, and Interference Flag = 1 + // Set a De_counter to wait IGI = upper bound. If time is UP, the Interference flag will be pull down. + if(Intf_HighTP_flag == 1) + { + De_counter--; + if(De_counter == 0) + { + Intf_HighTP_flag = 0; + psd_intf_flag = 0; + } + } +#endif + + //2 AGC RX High Power Mode by PSD only applied to STA Mode + //3 NOT applied 1. Ad Hoc Mode. + //3 NOT applied 2. AP Mode + if ((pMgntInfo->mAssoc) && (!pMgntInfo->mIbss) && (!ACTING_AS_AP(Adapter))) + { + Is40MHz = *(pDM_Odm->pBandWidth); + curRssi = pDM_Odm->RSSI_Min; + cur_channel = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, 0x0fff) & 0x0f; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RXHP RX HP flag = %d\n", pRX_HP_Table->RXHP_flag)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RXHP FA = %d\n", FalseAlmCnt->Cnt_all)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RXHP cur RSSI = %d, pre RSSI=%d\n", curRssi, preRssi)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RXHP current CH = %d\n", cur_channel)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RXHP Is 40MHz = %d\n", Is40MHz)); + //2 PSD function would be triggered + //3 1. Every 4 sec for PCIE + //3 2. Before TP Mode (Idle TP<4kbps) for USB + //3 3. After TP Mode (High TP) for USB + if((curRssi > 68) && (pRX_HP_Table->RXHP_flag == 0)) // Only RSSI>TH and RX_HP_flag=0 will Do PSD process + { +#if (DEV_BUS_TYPE == RT_USB_INTERFACE) + //2 Before TP Mode ==> PSD would be trigger every 4 sec + if(pRX_HP_Table->TP_Mode == Idle_Mode) //2.1 less wlan traffic <4kbps + { +#endif + if(PSDTriggerCnt == 1) + { + odm_PSD_RXHP(pDM_Odm); + pRX_HP_Table->PSD_func_trigger = 1; + PSDTriggerCnt = 0; + } + else + { + PSDTriggerCnt++; + } +#if(DEV_BUS_TYPE == RT_USB_INTERFACE) + } + //2 After TP Mode ==> Check if TP degrade larger than 20% would trigger PSD function + if(pRX_HP_Table->TP_Mode == High_TP_Mode) + { + if((pre_state_flag == 0)&&(LatchCnt == 0)) + { + // TP var < 5% + if((((curTPOkCnt-TP_Acc3)*20)<(TP_Acc3))&&(((curTPOkCnt-TP_Acc3)*20)>(-TP_Acc3))) + { + pre_state++; + if(pre_state == 3) // hit pre_state condition => consecutive 3 times + { + pre_state_flag = 1; + pre_state = 0; + } + + } + else + { + pre_state = 0; + } + } + //3 If pre_state_flag=1 ==> start to monitor TP degrade 20% + if(pre_state_flag == 1) + { + if(((TP_Acc3-curTPOkCnt)*5)>(TP_Acc3)) // degrade 20% + { + odm_PSD_RXHP(pDM_Odm); + pRX_HP_Table->PSD_func_trigger = 1; + TP_Degrade_flag = 1; + LatchCnt = 2; + pre_state_flag = 0; + } + else if(((TP_Buff[2]-curTPOkCnt)*5)>TP_Buff[2]) + { + odm_PSD_RXHP(pDM_Odm); + pRX_HP_Table->PSD_func_trigger = 1; + TP_Degrade_flag = 1; + LatchCnt = 2; + pre_state_flag = 0; + } + else if(((TP_Buff[3]-curTPOkCnt)*5)>TP_Buff[3]) + { + odm_PSD_RXHP(pDM_Odm); + pRX_HP_Table->PSD_func_trigger = 1; + TP_Degrade_flag = 1; + LatchCnt = 2; + pre_state_flag = 0; + } + } + } +#endif +} + +#if (DEV_BUS_TYPE == RT_USB_INTERFACE) + for (i=0;i<4;i++) + { + TP_Buff[4-i] = TP_Buff[3-i]; + } +#endif + //2 Update PSD bitmap according to PSD report + if((pRX_HP_Table->PSD_func_trigger == 1)&&(LatchCnt == 0)) + { + //2 Separate 80M bandwidth into 16 group with smaller 5M BW. + for (i = 0 ; i < 16 ; i++) + { + sum = 0; + for(j = 0; j < 5 ; j++) + sum += pRX_HP_Table->PSD_bitmap_RXHP[5*i + j]; + + if(sum < 5) + { + ch_map_intf_5M[i] = 1; // interference flag + } + } + //=============just for debug========================= + //for(i=0;i<16;i++) + //DbgPrint("RX HP: ch_map_intf_5M[%d] = %d\n", i, ch_map_intf_5M[i]); + //=============================================== + //2 Mask target channel 5M index + for(i = 0; i < (4+4*Is40MHz) ; i++) + { + ch_map_intf_5M[cur_channel - (1+2*Is40MHz) + i] = 0; + } + + psd_intf_flag = 0; + for(i = 0; i < 16; i++) + { + if(ch_map_intf_5M[i] == 1) + { + psd_intf_flag = 1; // interference is detected!!! + break; + } + } + +#if (DEV_BUS_TYPE == RT_USB_INTERFACE) + if(pRX_HP_Table->TP_Mode!=Idle_Mode) + { + if(psd_intf_flag == 1) // to avoid psd_intf_flag always 1 + { + Intf_HighTP_flag = 1; + De_counter = 32; // 0x1E -> 0x3E needs 32 times by each IGI step =1 + } + } +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RX HP psd_intf_flag = %d\n", psd_intf_flag)); + //2 Distance between target channel and interference + for(i = 0; i < 16; i++) + { + if(ch_map_intf_5M[i] == 1) + { + Intf_diff_idx = ((cur_channel+Is40MHz-(i+1))>0) ? (s1Byte)(cur_channel-2*Is40MHz-(i-2)) : (s1Byte)((i+1)-(cur_channel+2*Is40MHz)); + if(Intf_diff_idx < MIN_Intf_diff_idx) + MIN_Intf_diff_idx = Intf_diff_idx; // the min difference index between interference and target + } + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RX HP MIN_Intf_diff_idx = %d\n", MIN_Intf_diff_idx)); + //2 Choose False Alarm Threshold + switch (MIN_Intf_diff_idx){ + case 0: + case 1: + case 2: + case 3: + FA_TH = FA_RXHP_TH1; + break; + case 4: // CH5 + case 5: // CH6 + FA_TH = FA_RXHP_TH2; + break; + case 6: // CH7 + case 7: // CH8 + FA_TH = FA_RXHP_TH3; + break; + case 8: // CH9 + case 9: //CH10 + FA_TH = FA_RXHP_TH4; + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + FA_TH = FA_RXHP_TH5; + break; + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("RX HP FA_TH = %d\n", FA_TH)); + pRX_HP_Table->PSD_func_trigger = 0; + } + //1 Monitor RSSI variation to choose the suitable IGI or Exit AGC RX High Power Mode + if(pRX_HP_Table->RXHP_flag == 1) + { + if ((curRssi > 80)&&(preRssi < 80)) + { + pRX_HP_Table->Cur_IGI = LNA_Low_Gain_1; + } + else if ((curRssi < 80)&&(preRssi > 80)) + { + pRX_HP_Table->Cur_IGI = LNA_Low_Gain_2; + } + else if ((curRssi > 72)&&(preRssi < 72)) + { + pRX_HP_Table->Cur_IGI = LNA_Low_Gain_2; + } + else if ((curRssi < 72)&&( preRssi > 72)) + { + pRX_HP_Table->Cur_IGI = LNA_Low_Gain_3; + } + else if (curRssi < 68) //RSSI is NOT large enough!!==> Exit AGC RX High Power Mode + { + pRX_HP_Table->Cur_pw_th = pw_th_10dB; + pRX_HP_Table->RXHP_flag = 0; // Back to Normal DIG Mode + psd_intf_flag = 0; + } + } + else // pRX_HP_Table->RXHP_flag == 0 + { + //1 Decide whether to enter AGC RX High Power Mode + if ((curRssi > 70) && (psd_intf_flag == 1) && (FalseAlmCnt->Cnt_all > FA_TH) && + (pDM_DigTable->CurIGValue == pDM_DigTable->rx_gain_range_max)) + { + if (curRssi > 80) + { + pRX_HP_Table->Cur_IGI = LNA_Low_Gain_1; + } + else if (curRssi > 72) + { + pRX_HP_Table->Cur_IGI = LNA_Low_Gain_2; + } + else + { + pRX_HP_Table->Cur_IGI = LNA_Low_Gain_3; + } + pRX_HP_Table->Cur_pw_th = pw_th_16dB; //RegC54[9:8]=2'b11: to enter AGC Flow 3 + pRX_HP_Table->First_time_enter = TRUE; + pRX_HP_Table->RXHP_flag = 1; // RXHP_flag=1: AGC RX High Power Mode, RXHP_flag=0: Normal DIG Mode + } + } + preRssi = curRssi; + odm_Write_RXHP(pDM_Odm); + } +#endif //#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN)) +#endif //#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) | (DEV_BUS_TYPE == RT_USB_INTERFACE) +} + + +VOID +odm_PSD_RXHPCallback( + PRT_TIMER pTimer +) +{ + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + pRXHP_T pRX_HP_Table = &pDM_Odm->DM_RXHP_Table; + +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + #if USE_WORKITEM + ODM_ScheduleWorkItem(&pRX_HP_Table->PSDTimeWorkitem); + #else + odm_PSD_RXHP(pDM_Odm); + #endif +#else + ODM_ScheduleWorkItem(&pRX_HP_Table->PSDTimeWorkitem); +#endif + + } + +VOID +odm_PSD_RXHPWorkitemCallback( + IN PVOID pContext + ) +{ + PADAPTER pAdapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + odm_PSD_RXHP(pDM_Odm); +} + +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RXHP.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RXHP.h new file mode 100755 index 000000000000..ef07bba0119f --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RXHP.h @@ -0,0 +1,105 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __PHYDMRXHP_H__ +#define __PHYDMRXHP_H__ + +#define RXHP_VERSION "1.0" + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#define AFH_PSD 1 //0:normal PSD scan, 1: only do 20 pts PSD +#define MODE_40M 0 //0:20M, 1:40M +#define PSD_TH2 3 +#define PSD_CHMIN 20 // Minimum channel number for BT AFH +#define SIR_STEP_SIZE 3 +#define Smooth_Size_1 5 +#define Smooth_TH_1 3 +#define Smooth_Size_2 10 +#define Smooth_TH_2 4 +#define Smooth_Size_3 20 +#define Smooth_TH_3 4 +#define Smooth_Step_Size 5 +#define Adaptive_SIR 1 +#define PSD_RESCAN 4 +#define PSD_SCAN_INTERVAL 700 //ms + +typedef struct _RX_High_Power_ +{ + u1Byte RXHP_flag; + u1Byte PSD_func_trigger; + u1Byte PSD_bitmap_RXHP[80]; + u1Byte Pre_IGI; + u1Byte Cur_IGI; + u1Byte Pre_pw_th; + u1Byte Cur_pw_th; + BOOLEAN First_time_enter; + BOOLEAN RXHP_enable; + u1Byte TP_Mode; + RT_TIMER PSDTimer; + #if USE_WORKITEM + RT_WORK_ITEM PSDTimeWorkitem; + #endif +}RXHP_T, *pRXHP_T; + +#define dm_PSDMonitorCallback odm_PSDMonitorCallback +VOID odm_PSDMonitorCallback(PRT_TIMER pTimer); + +VOID +odm_PSDMonitorInit( + IN PVOID pDM_VOID + ); + +void odm_RXHPInit( + IN PVOID pDM_VOID); + +void odm_RXHP( + IN PVOID pDM_VOID); + +VOID +odm_PSD_RXHPCallback( + PRT_TIMER pTimer +); + + VOID +ODM_PSDDbgControl( + IN PADAPTER Adapter, + IN u4Byte mode, + IN u4Byte btRssi + ); + + VOID +odm_PSD_RXHPCallback( + PRT_TIMER pTimer +); + +VOID +odm_PSD_RXHPWorkitemCallback( + IN PVOID pContext + ); + +VOID +odm_PSDMonitorWorkItemCallback( + IN PVOID pContext + ); + + #endif + + #endif + \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RaInfo.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RaInfo.c new file mode 100755 index 000000000000..0e7873745a3a --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RaInfo.c @@ -0,0 +1,1595 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + + +VOID +odm_RSSIMonitorInit( + IN PVOID pDM_VOID + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + pRA_Table->firstconnect = FALSE; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + pRA_Table->PT_collision_pre = TRUE; //used in ODM_DynamicARFBSelect(WIN only) +#endif +#endif +} + + +VOID +odm_RSSIMonitorCheck( + IN PVOID pDM_VOID + ) +{ + // + // For AP/ADSL use prtl8192cd_priv + // For CE/NIC use PADAPTER + // +PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) + return; + + // + // 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate + // at the same time. In the stage2/3, we need to prive universal interface and merge all + // HW dynamic mechanism. + // + switch (pDM_Odm->SupportPlatform) + { + case ODM_WIN: + odm_RSSIMonitorCheckMP(pDM_Odm); + break; + + case ODM_CE: + odm_RSSIMonitorCheckCE(pDM_Odm); + break; + + case ODM_AP: + odm_RSSIMonitorCheckAP(pDM_Odm); + break; + + case ODM_ADSL: + //odm_DIGAP(pDM_Odm); + break; + } + +} // odm_RSSIMonitorCheck + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +odm_RSSIDumpToRegister( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + PlatformEFIOWrite1Byte(Adapter, rA_RSSIDump_Jaguar, Adapter->RxStats.RxRSSIPercentage[0]); + PlatformEFIOWrite1Byte(Adapter, rB_RSSIDump_Jaguar, Adapter->RxStats.RxRSSIPercentage[1]); + + // Rx EVM + PlatformEFIOWrite1Byte(Adapter, rS1_RXevmDump_Jaguar, Adapter->RxStats.RxEVMdbm[0]); + PlatformEFIOWrite1Byte(Adapter, rS2_RXevmDump_Jaguar, Adapter->RxStats.RxEVMdbm[1]); + + // Rx SNR + PlatformEFIOWrite1Byte(Adapter, rA_RXsnrDump_Jaguar, (u1Byte)(Adapter->RxStats.RxSNRdB[0])); + PlatformEFIOWrite1Byte(Adapter, rB_RXsnrDump_Jaguar, (u1Byte)(Adapter->RxStats.RxSNRdB[1])); + + // Rx Cfo_Short + PlatformEFIOWrite2Byte(Adapter, rA_CfoShortDump_Jaguar, Adapter->RxStats.RxCfoShort[0]); + PlatformEFIOWrite2Byte(Adapter, rB_CfoShortDump_Jaguar, Adapter->RxStats.RxCfoShort[1]); + + // Rx Cfo_Tail + PlatformEFIOWrite2Byte(Adapter, rA_CfoLongDump_Jaguar, Adapter->RxStats.RxCfoTail[0]); + PlatformEFIOWrite2Byte(Adapter, rB_CfoLongDump_Jaguar, Adapter->RxStats.RxCfoTail[1]); + } + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + PlatformEFIOWrite1Byte(Adapter, rA_RSSIDump_92E, Adapter->RxStats.RxRSSIPercentage[0]); + PlatformEFIOWrite1Byte(Adapter, rB_RSSIDump_92E, Adapter->RxStats.RxRSSIPercentage[1]); + // Rx EVM + PlatformEFIOWrite1Byte(Adapter, rS1_RXevmDump_92E, Adapter->RxStats.RxEVMdbm[0]); + PlatformEFIOWrite1Byte(Adapter, rS2_RXevmDump_92E, Adapter->RxStats.RxEVMdbm[1]); + // Rx SNR + PlatformEFIOWrite1Byte(Adapter, rA_RXsnrDump_92E, (u1Byte)(Adapter->RxStats.RxSNRdB[0])); + PlatformEFIOWrite1Byte(Adapter, rB_RXsnrDump_92E, (u1Byte)(Adapter->RxStats.RxSNRdB[1])); + // Rx Cfo_Short + PlatformEFIOWrite2Byte(Adapter, rA_CfoShortDump_92E, Adapter->RxStats.RxCfoShort[0]); + PlatformEFIOWrite2Byte(Adapter, rB_CfoShortDump_92E, Adapter->RxStats.RxCfoShort[1]); + // Rx Cfo_Tail + PlatformEFIOWrite2Byte(Adapter, rA_CfoLongDump_92E, Adapter->RxStats.RxCfoTail[0]); + PlatformEFIOWrite2Byte(Adapter, rB_CfoLongDump_92E, Adapter->RxStats.RxCfoTail[1]); + } +} +#endif + +VOID +odm_RSSIMonitorCheckMP( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PRT_WLAN_STA pEntry = NULL; + u1Byte i; + s4Byte tmpEntryMaxPWDB=0, tmpEntryMinPWDB=0xff; + u1Byte H2C_Parameter[4] ={0}; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PMGNT_INFO pDefaultMgntInfo = &Adapter->MgntInfo; + u8Byte curTxOkCnt = 0, curRxOkCnt = 0; + u1Byte STBC_TX = 0; + BOOLEAN FirstConnect; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + +#if (BEAMFORMING_SUPPORT == 1) + BEAMFORMING_CAP Beamform_cap = BEAMFORMING_CAP_NONE; + u1Byte TxBF_EN = 0; +#endif + + PADAPTER pLoopAdapter = GetDefaultAdapter(Adapter); + + BOOLEAN bExtRAInfo = FALSE; + + if(pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8821 || pDM_Odm->SupportICType == ODM_RTL8723B) + bExtRAInfo = TRUE; + + FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == FALSE); + pRA_Table->firstconnect = pHalData->bLinked; + H2C_Parameter[3] |= FirstConnect << 5; + + if(pDM_Odm->SupportICType == ODM_RTL8188E && (pDefaultMgntInfo->CustomerID==RT_CID_819x_HP)) + { + if(curRxOkCnt >(curTxOkCnt*6)) + PlatformEFIOWrite4Byte(Adapter, REG_ARFR0, 0x8f015); + else + PlatformEFIOWrite4Byte(Adapter, REG_ARFR0, 0xff015); + } + + if(pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8821) + { + if(curRxOkCnt >(curTxOkCnt*6)) + H2C_Parameter[3]=0x01; + else + H2C_Parameter[3]=0x00; + } + + while(pLoopAdapter) + { + + if(pLoopAdapter != NULL){ + pMgntInfo = &pLoopAdapter->MgntInfo; + curTxOkCnt = pLoopAdapter->TxStats.NumTxBytesUnicast - pMgntInfo->lastTxOkCnt; + curRxOkCnt = pLoopAdapter->RxStats.NumRxBytesUnicast - pMgntInfo->lastRxOkCnt; + pMgntInfo->lastTxOkCnt = curTxOkCnt; + pMgntInfo->lastRxOkCnt = curRxOkCnt; + } + + for(i = 0; i < ASSOCIATE_ENTRY_NUM; i++) + { + + if(IsAPModeExist(pLoopAdapter)) + { + if(GetFirstExtAdapter(pLoopAdapter) != NULL && + GetFirstExtAdapter(pLoopAdapter) == pLoopAdapter){ + pEntry = AsocEntry_EnumStation(pLoopAdapter, i); + } + else if(GetFirstGOPort(pLoopAdapter) != NULL && + IsFirstGoAdapter(pLoopAdapter)){ + pEntry = AsocEntry_EnumStation(pLoopAdapter, i); + } + } + else + { + if(GetDefaultAdapter(pLoopAdapter) == pLoopAdapter){ + pEntry = AsocEntry_EnumStation(pLoopAdapter, i); + } + } + + if(pEntry != NULL) + { + if(pEntry->bAssociated) + { + + RT_DISP_ADDR(FDM, DM_PWDB, ("pEntry->MacAddr ="), pEntry->MacAddr); + RT_DISP(FDM, DM_PWDB, ("pEntry->rssi = 0x%x(%d)\n", + pEntry->rssi_stat.UndecoratedSmoothedPWDB, pEntry->rssi_stat.UndecoratedSmoothedPWDB)); + + if(bExtRAInfo) + { + +#if (BEAMFORMING_SUPPORT == 1) + Beamform_cap = Beamforming_GetEntryBeamCapByMacId(Adapter, pEntry->AssociatedMacId); + if(Beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT |BEAMFORMER_CAP_VHT_SU)) + TxBF_EN = 1; + else + TxBF_EN = 0; + + H2C_Parameter[3] |= TxBF_EN << 6; + + if(TxBF_EN) + STBC_TX = 0; + else +#endif + { + if(IS_WIRELESS_MODE_AC(Adapter)) + STBC_TX = TEST_FLAG(pEntry->VHTInfo.STBC, STBC_VHT_ENABLE_TX); + else + STBC_TX = TEST_FLAG(pEntry->HTInfo.STBC, STBC_HT_ENABLE_TX); + } + + H2C_Parameter[3] |= STBC_TX << 1; + } + + if(pEntry->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) + tmpEntryMinPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; + if(pEntry->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) + tmpEntryMaxPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; + + H2C_Parameter[2] = (u1Byte)(pEntry->rssi_stat.UndecoratedSmoothedPWDB & 0xFF); + H2C_Parameter[1] = 0x20; // fw v12 cmdid 5:use max macid ,for nic ,default macid is 0 ,max macid is 1 + H2C_Parameter[0] = (pEntry->AssociatedMacId); + if(bExtRAInfo) + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, 4, H2C_Parameter); + else + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, 3, H2C_Parameter); + } + } + else + { + break; + } + } + + pLoopAdapter = GetNextExtAdapter(pLoopAdapter); + } + + if(tmpEntryMaxPWDB != 0) // If associated entry is found + { + pHalData->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB; + RT_DISP(FDM, DM_PWDB, ("EntryMaxPWDB = 0x%x(%d)\n", tmpEntryMaxPWDB, tmpEntryMaxPWDB)); + } + else + { + pHalData->EntryMaxUndecoratedSmoothedPWDB = 0; + } + + if(tmpEntryMinPWDB != 0xff) // If associated entry is found + { + pHalData->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; + RT_DISP(FDM, DM_PWDB, ("EntryMinPWDB = 0x%x(%d)\n", tmpEntryMinPWDB, tmpEntryMinPWDB)); + + } + else + { + pHalData->EntryMinUndecoratedSmoothedPWDB = 0; + } + + // Indicate Rx signal strength to FW. + if(pHalData->bUseRAMask) + { + if(bExtRAInfo) + { + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pDefaultMgntInfo); + PRT_VERY_HIGH_THROUGHPUT pVHTInfo = GET_VHT_INFO(pDefaultMgntInfo); + +#if (BEAMFORMING_SUPPORT == 1) + + Beamform_cap = Beamforming_GetEntryBeamCapByMacId(Adapter, pDefaultMgntInfo->mMacId); + + if(Beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT |BEAMFORMER_CAP_VHT_SU)) + TxBF_EN = 1; + else + TxBF_EN = 0; + + H2C_Parameter[3] |= TxBF_EN << 6; + + if(TxBF_EN) + STBC_TX = 0; + else +#endif + { + if(IS_WIRELESS_MODE_AC(Adapter)) + STBC_TX = TEST_FLAG(pVHTInfo->VhtCurStbc, STBC_VHT_ENABLE_TX); + else + STBC_TX = TEST_FLAG(pHTInfo->HtCurStbc, STBC_HT_ENABLE_TX); + } + + H2C_Parameter[3] |= STBC_TX << 1; + } + + H2C_Parameter[2] = (u1Byte)(pHalData->UndecoratedSmoothedPWDB & 0xFF); + H2C_Parameter[1] = 0x20; // fw v12 cmdid 5:use max macid ,for nic ,default macid is 0 ,max macid is 1 + H2C_Parameter[0] = 0; // fw v12 cmdid 5:use max macid ,for nic ,default macid is 0 ,max macid is 1 + if(bExtRAInfo) + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, 4, H2C_Parameter); + else + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, 3, H2C_Parameter); + + // BT 3.0 HS mode Rssi + if(pDM_Odm->bBtHsOperation) + { + H2C_Parameter[2] = pDM_Odm->btHsRssi; + H2C_Parameter[1] = 0x0; + H2C_Parameter[0] = 2; + if(bExtRAInfo) + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, 4, H2C_Parameter); + else + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, 3, H2C_Parameter); + } + } + else + { + PlatformEFIOWrite1Byte(Adapter, 0x4fe, (u1Byte)pHalData->UndecoratedSmoothedPWDB); + } + + if((pDM_Odm->SupportICType == ODM_RTL8812)||(pDM_Odm->SupportICType == ODM_RTL8192E)) + odm_RSSIDumpToRegister(pDM_Odm); + + + { + PADAPTER pLoopAdapter = GetDefaultAdapter(Adapter); + s4Byte GlobalRSSI_min = 0xFF, LocalRSSI_Min; + BOOLEAN bLink= FALSE; + + while(pLoopAdapter) + { + LocalRSSI_Min = odm_FindMinimumRSSI(pLoopAdapter); + //DbgPrint("pHalData->bLinked=%d, LocalRSSI_Min=%d\n", pHalData->bLinked, LocalRSSI_Min); + if((LocalRSSI_Min < GlobalRSSI_min) && (LocalRSSI_Min != 0)) + GlobalRSSI_min = LocalRSSI_Min; + + if(pHalData->bLinked) + bLink = TRUE; + + pLoopAdapter = GetNextExtAdapter(pLoopAdapter); + } + + pHalData->bLinked = bLink; + ODM_CmnInfoUpdate(&pHalData->DM_OutSrc ,ODM_CMNINFO_LINK, (u8Byte)bLink); + ODM_CmnInfoUpdate(&pHalData->DM_OutSrc ,ODM_CMNINFO_RSSI_MIN, (u8Byte)GlobalRSSI_min); + + } + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +} + +#if(DM_ODM_SUPPORT_TYPE==ODM_CE) +// +//sherry move from DUSC to here 20110517 +// +static VOID +FindMinimumRSSI_Dmsp( + IN PADAPTER pAdapter +) +{ +#if 0 + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + s32 Rssi_val_min_back_for_mac0; + BOOLEAN bGetValueFromBuddyAdapter = dm_DualMacGetParameterFromBuddyAdapter(pAdapter); + BOOLEAN bRestoreRssi = _FALSE; + PADAPTER BuddyAdapter = pAdapter->BuddyAdapter; + + if(pHalData->MacPhyMode92D == DUALMAC_SINGLEPHY) + { + if(BuddyAdapter!= NULL) + { + if(pHalData->bSlaveOfDMSP) + { + //ODM_RT_TRACE(pDM_Odm,COMP_EASY_CONCURRENT,DBG_LOUD,("bSlavecase of dmsp\n")); + BuddyAdapter->DualMacDMSPControl.RssiValMinForAnotherMacOfDMSP = pdmpriv->MinUndecoratedPWDBForDM; + } + else + { + if(bGetValueFromBuddyAdapter) + { + //ODM_RT_TRACE(pDM_Odm,COMP_EASY_CONCURRENT,DBG_LOUD,("get new RSSI\n")); + bRestoreRssi = _TRUE; + Rssi_val_min_back_for_mac0 = pdmpriv->MinUndecoratedPWDBForDM; + pdmpriv->MinUndecoratedPWDBForDM = pAdapter->DualMacDMSPControl.RssiValMinForAnotherMacOfDMSP; + } + } + } + + } + + if(bRestoreRssi) + { + bRestoreRssi = _FALSE; + pdmpriv->MinUndecoratedPWDBForDM = Rssi_val_min_back_for_mac0; + } +#endif +} + +static void +FindMinimumRSSI( +IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + //1 1.Determine the minimum RSSI + + if((pDM_Odm->bLinked != _TRUE) && + (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) + { + pdmpriv->MinUndecoratedPWDBForDM = 0; + //ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("Not connected to any \n")); + } + else + { + pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + } + + //DBG_8192C("%s=>MinUndecoratedPWDBForDM(%d)\n",__FUNCTION__,pdmpriv->MinUndecoratedPWDBForDM); + //ODM_RT_TRACE(pDM_Odm,COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",pHalData->MinUndecoratedPWDBForDM)); +} +#endif + +VOID +odm_RSSIMonitorCheckCE( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); + int i; + int tmpEntryMaxPWDB=0, tmpEntryMinPWDB=0xff; + u8 sta_cnt=0; + u32 UL_DL_STATE = 0, STBC_TX = 0, TxBF_EN = 0; + u32 PWDB_rssi[NUM_STA]={0};//[0~15]:MACID, [16~31]:PWDB_rssi + BOOLEAN FirstConnect = FALSE; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + + if(pDM_Odm->bLinked != _TRUE) + return; + + #if((RTL8812A_SUPPORT==1)||(RTL8821A_SUPPORT==1)) + if((pDM_Odm->SupportICType == ODM_RTL8812)||(pDM_Odm->SupportICType == ODM_RTL8821)) + { + u64 curTxOkCnt = pdvobjpriv->traffic_stat.cur_tx_bytes; + u64 curRxOkCnt = pdvobjpriv->traffic_stat.cur_rx_bytes; + + if(curRxOkCnt >(curTxOkCnt*6)) + UL_DL_STATE = 1; + else + UL_DL_STATE = 0; + } + #endif + + FirstConnect = (pDM_Odm->bLinked) && (pRA_Table->firstconnect == FALSE); + pRA_Table->firstconnect = pDM_Odm->bLinked; + + //if(check_fwstate(&Adapter->mlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + #if 1 + struct sta_info *psta; + + for(i=0; ipODM_StaInfo[i])) + { + if(IS_MCAST( psta->hwaddr)) //if(psta->mac_id ==1) + continue; + + if(psta->rssi_stat.UndecoratedSmoothedPWDB == (-1)) + continue; + + if(psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) + tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + + if(psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) + tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + + #if 0 + DBG_871X("%s mac_id:%u, mac:"MAC_FMT", rssi:%d\n", __func__, + psta->mac_id, MAC_ARG(psta->hwaddr), psta->rssi_stat.UndecoratedSmoothedPWDB); + #endif + + if(psta->rssi_stat.UndecoratedSmoothedPWDB != (-1)) { + +#ifdef CONFIG_80211N_HT + if(pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8812) + { +#ifdef CONFIG_BEAMFORMING + BEAMFORMING_CAP Beamform_cap = beamforming_get_entry_beam_cap_by_mac_id(&Adapter->mlmepriv, psta->mac_id); + + if(Beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT |BEAMFORMER_CAP_VHT_SU)) + TxBF_EN = 1; + else + TxBF_EN = 0; + + if (TxBF_EN) { + STBC_TX = 0; + } + else +#endif + { +#ifdef CONFIG_80211AC_VHT + if(IsSupportedVHT(psta->wireless_mode)) + STBC_TX = TEST_FLAG(psta->vhtpriv.stbc_cap, STBC_VHT_ENABLE_TX); + else +#endif + STBC_TX = TEST_FLAG(psta->htpriv.stbc_cap, STBC_HT_ENABLE_TX); + } + } +#endif + + if(pDM_Odm->SupportICType == ODM_RTL8192D) + PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16) | ((Adapter->stapriv.asoc_sta_count+1) << 8)); + else if ((pDM_Odm->SupportICType == ODM_RTL8192E)||(pDM_Odm->SupportICType == ODM_RTL8812)||(pDM_Odm->SupportICType == ODM_RTL8821)) + PWDB_rssi[sta_cnt++] = (((u8)(psta->mac_id&0xFF)) | ((psta->rssi_stat.UndecoratedSmoothedPWDB&0x7F)<<16) |(STBC_TX << 25) | (FirstConnect << 29) | (TxBF_EN << 30)); + else + PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16) ); + } + } + } + #else + _irqL irqL; + _list *plist, *phead; + struct sta_info *psta; + struct sta_priv *pstapriv = &Adapter->stapriv; + u8 bcast_addr[ETH_ALEN]= {0xff,0xff,0xff,0xff,0xff,0xff}; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for(i=0; i< NUM_STA; i++) + { + phead = &(pstapriv->sta_hash[i]); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + + plist = get_next(plist); + + if(_rtw_memcmp(psta->hwaddr, bcast_addr, ETH_ALEN) || + _rtw_memcmp(psta->hwaddr, myid(&Adapter->eeprompriv), ETH_ALEN)) + continue; + + if(psta->state & WIFI_ASOC_STATE) + { + + if(psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) + tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + + if(psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) + tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + + if(psta->rssi_stat.UndecoratedSmoothedPWDB != (-1)){ + //printk("%s==> mac_id(%d),rssi(%d)\n",__FUNCTION__,psta->mac_id,psta->rssi_stat.UndecoratedSmoothedPWDB); + #if(RTL8192D_SUPPORT==1) + PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16) | ((Adapter->stapriv.asoc_sta_count+1) << 8)); + #else + PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16) ); + #endif + } + } + + } + + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + #endif + + //printk("%s==> sta_cnt(%d)\n",__FUNCTION__,sta_cnt); + + for(i=0; i< sta_cnt; i++) + { + if(PWDB_rssi[i] != (0)){ + if(pHalData->fw_ractrl == _TRUE)// Report every sta's RSSI to FW + { + #if(RTL8192D_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8192D){ + FillH2CCmd92D(Adapter, H2C_RSSI_REPORT, 3, (u8 *)(&PWDB_rssi[i])); + } + #endif + + #if((RTL8192C_SUPPORT==1)||(RTL8723A_SUPPORT==1)) + if((pDM_Odm->SupportICType == ODM_RTL8192C)||(pDM_Odm->SupportICType == ODM_RTL8723A)){ + rtl8192c_set_rssi_cmd(Adapter, (u8*)&PWDB_rssi[i]); + } + #endif + + #if((RTL8812A_SUPPORT==1)||(RTL8821A_SUPPORT==1)) + if((pDM_Odm->SupportICType == ODM_RTL8812)||(pDM_Odm->SupportICType == ODM_RTL8821)){ + PWDB_rssi[i] |= (UL_DL_STATE << 24); + rtl8812_set_rssi_cmd(Adapter, (u8 *)(&PWDB_rssi[i])); + } + #endif + #if(RTL8192E_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8192E){ + rtl8192e_set_rssi_cmd(Adapter, (u8 *)(&PWDB_rssi[i])); + } + #endif + #if(RTL8723B_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8723B){ + rtl8723b_set_rssi_cmd(Adapter, (u8 *)(&PWDB_rssi[i])); + } + #endif + + #if(RTL8188E_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8188E){ + rtl8188e_set_rssi_cmd(Adapter, (u8 *)(&PWDB_rssi[i])); + } + #endif + + } + else{ + #if((RTL8188E_SUPPORT==1)&&(RATE_ADAPTIVE_SUPPORT == 1)) + if(pDM_Odm->SupportICType == ODM_RTL8188E){ + ODM_RA_SetRSSI_8188E( + &(pHalData->odmpriv), (PWDB_rssi[i]&0xFF), (u8)((PWDB_rssi[i]>>16) & 0xFF)); + } + #endif + } + } + } + } + + + + if(tmpEntryMaxPWDB != 0) // If associated entry is found + { + pdmpriv->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB; + } + else + { + pdmpriv->EntryMaxUndecoratedSmoothedPWDB = 0; + } + + if(tmpEntryMinPWDB != 0xff) // If associated entry is found + { + pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; + } + else + { + pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0; + } + + FindMinimumRSSI(Adapter);//get pdmpriv->MinUndecoratedPWDBForDM + + #if(RTL8192D_SUPPORT==1) + FindMinimumRSSI_Dmsp(Adapter); + #endif + pDM_Odm->RSSI_Min = pdmpriv->MinUndecoratedPWDBForDM; + //ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM); +#endif//if (DM_ODM_SUPPORT_TYPE == ODM_CE) +} + + +VOID +odm_RSSIMonitorCheckAP( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#if defined(CONFIG_RTL_92C_SUPPORT) || defined(CONFIG_RTL_92D_SUPPORT) ||defined(CONFIG_RTL_8812_SUPPORT)||defined(CONFIG_WLAN_HAL_8881A)||defined(CONFIG_WLAN_HAL_8192EE) + { + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + prtl8192cd_priv priv = pDM_Odm->priv; + u4Byte i; + PSTA_INFO_T pstat; + static u1Byte H2C_Parameter[5]; + u1Byte TxBF_EN = 0; + pBDC_T pDM_BdcTable = &pDM_Odm->DM_BdcTable; + + if( priv->up_time % 2 ) + return; + + pDM_BdcTable->num_Txbfee_Client=0; + pDM_BdcTable->num_Txbfer_Client=0; + //pDM_BdcTable->num_Client=0; + + for(i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pstat) ) + { +#ifdef BEAMFORMING_SUPPORT + BEAMFORMING_CAP Beamform_cap = Beamforming_GetEntryBeamCapByMacId(priv, pstat->aid); + if(Beamform_cap == BEAMFORMER_CAP_HT_EXPLICIT || Beamform_cap == BEAMFORMER_CAP_VHT_SU || + Beamform_cap == (BEAMFORMER_CAP_HT_EXPLICIT|BEAMFORMEE_CAP_HT_EXPLICIT) || + Beamform_cap == (BEAMFORMER_CAP_VHT_SU|BEAMFORMEE_CAP_VHT_SU)) + { + TxBF_EN = (1<< 6); + pDM_BdcTable->w_BFee_Client[i]=1; //AP act as BFer + pDM_BdcTable->num_Txbfee_Client++; + } + else + { + pDM_BdcTable->w_BFee_Client[i]=0; //AP act as BFer + } + + if((Beamform_cap & BEAMFORMEE_CAP_HT_EXPLICIT) || (Beamform_cap & BEAMFORMEE_CAP_VHT_SU) ) + { + pDM_BdcTable->w_BFer_Client[i]=1; //AP act as BFee + pDM_BdcTable->num_Txbfer_Client++; + } + else + { + pDM_BdcTable->w_BFer_Client[i]=0; //AP act as BFer + } + + + //pDM_BdcTable->num_Client++; + + + +#endif +//#ifdef STA_EXT +// if (GET_CHIP_VER(priv)==VERSION_8812E && REMAP_AID(pstat) < (RTL8812_NUM_STAT - 1)) +//#endif + { +#ifdef CONFIG_RTL_8812_SUPPORT +#ifdef STA_EXT + if(REMAP_AID(pstat) < (RTL8812_NUM_STAT - 1)) +#endif + + if(pDM_Odm->SupportICType == ODM_RTL8812) { + memset(H2C_Parameter,0,5); + H2C_Parameter[2] = (u1Byte)(pstat->rssi & 0x7F); + H2C_Parameter[0] = REMAP_AID(pstat); + if ((priv->pmib->dot11nConfigEntry.dot11nSTBC) && ( + (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_RX_STBC_CAP_) +#ifdef RTK_AC_SUPPORT + || (pstat->vht_cap_buf.vht_cap_info & cpu_to_le32(_VHTCAP_RX_STBC_CAP_)) +#endif + ))) + H2C_Parameter[3] |= 2; + H2C_Parameter[3] |= TxBF_EN ; + FillH2CCmd8812(pDM_Odm->priv, H2C_8812_RSSI_REPORT, 4, H2C_Parameter); + } +#endif + } +//#ifdef STA_EXT +// else if (GET_CHIP_VER(priv)!=VERSION_8812E && REMAP_AID(pstat) < (FW_NUM_STAT - 1)) +//#endif + { +#if defined(CONFIG_WLAN_HAL_8881A) || defined(CONFIG_WLAN_HAL_8192EE) +#ifdef STA_EXT + if(REMAP_AID(pstat) < (RTL8812_NUM_STAT - 1)) +#endif + if(pDM_Odm->SupportICType == ODM_RTL8881A || pDM_Odm->SupportICType == ODM_RTL8192E) { +// u1Byte H2C_Parameter[5] ={0}; + u1Byte cmdlen = 3; + memset(H2C_Parameter, 0, 5); + H2C_Parameter[2] = (u1Byte)(pstat->rssi & 0xFF); + H2C_Parameter[0] = REMAP_AID(pstat); + if(pDM_Odm->SupportICType == ODM_RTL8192E) { + cmdlen = 4; + if ((priv->pmib->dot11nConfigEntry.dot11nSTBC) && (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_RX_STBC_CAP_))) + H2C_Parameter[3] |= 2; + H2C_Parameter[3] |= TxBF_EN; + + } + GET_HAL_INTERFACE(pDM_Odm->priv)->FillH2CCmdHandler(pDM_Odm->priv, H2C_88XX_RSSI_REPORT, cmdlen, H2C_Parameter); + } +#endif + +#if defined(CONFIG_RTL_92C_SUPPORT) || defined(CONFIG_RTL_92D_SUPPORT) +#ifdef STA_EXT + if(REMAP_AID(pstat) < (FW_NUM_STAT - 1)) +#endif + if(pDM_Odm->SupportICType == ODM_RTL8192C || pDM_Odm->SupportICType == ODM_RTL8192D) + add_update_rssi(pDM_Odm->priv, pstat); +#endif + } + + } + } + } +#endif +#endif + +} + + +VOID +odm_RateAdaptiveMaskInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_RATE_ADAPTIVE pOdmRA = &pDM_Odm->RateAdaptive; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PMGNT_INFO pMgntInfo = &pDM_Odm->Adapter->MgntInfo; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pDM_Odm->Adapter); + + pMgntInfo->Ratr_State = DM_RATR_STA_INIT; + + if (pMgntInfo->DM_Type == DM_Type_ByDriver) + pHalData->bUseRAMask = TRUE; + else + pHalData->bUseRAMask = FALSE; + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + pOdmRA->Type = DM_Type_ByDriver; + if (pOdmRA->Type == DM_Type_ByDriver) + pDM_Odm->bUseRAMask = _TRUE; + else + pDM_Odm->bUseRAMask = _FALSE; +#endif + + pOdmRA->RATRState = DM_RATR_STA_INIT; + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + if(pDM_Odm->SupportICType == ODM_RTL8812) + pOdmRA->LdpcThres = 50; + else + pOdmRA->LdpcThres = 35; + + pOdmRA->RtsThres = 35; + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + pOdmRA->LdpcThres = 35; + pOdmRA->bUseLdpc = FALSE; + +#else + pOdmRA->UltraLowRSSIThresh = 9; + +#endif + + pOdmRA->HighRSSIThresh = 50; + pOdmRA->LowRSSIThresh = 20; +} +/*----------------------------------------------------------------------------- + * Function: odm_RefreshRateAdaptiveMask() + * + * Overview: Update rate table mask according to rssi + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/27/2009 hpfan Create Version 0. + * + *---------------------------------------------------------------------------*/ +VOID +odm_RefreshRateAdaptiveMask( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, ("odm_RefreshRateAdaptiveMask()---------->\n")); + if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, ("odm_RefreshRateAdaptiveMask(): Return cos not supported\n")); + return; + } + // + // 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate + // at the same time. In the stage2/3, we need to prive universal interface and merge all + // HW dynamic mechanism. + // + switch (pDM_Odm->SupportPlatform) + { + case ODM_WIN: + odm_RefreshRateAdaptiveMaskMP(pDM_Odm); + break; + + case ODM_CE: + odm_RefreshRateAdaptiveMaskCE(pDM_Odm); + break; + + case ODM_AP: + case ODM_ADSL: + odm_RefreshRateAdaptiveMaskAPADSL(pDM_Odm); + break; + } + +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +odm_RefreshLdpcRtsMP( + IN PADAPTER pAdapter, + IN PDM_ODM_T pDM_Odm, + IN u1Byte mMacId, + IN u1Byte IOTPeer, + IN s4Byte UndecoratedSmoothedPWDB + ) +{ + BOOLEAN bCtlLdpc = FALSE; + PMGNT_INFO pMgntInfo = GetDefaultMgntInfo(pAdapter); + PODM_RATE_ADAPTIVE pRA = &pDM_Odm->RateAdaptive; + + if(pDM_Odm->SupportICType != ODM_RTL8821 && pDM_Odm->SupportICType != ODM_RTL8812) + return; + + if((pDM_Odm->SupportICType == ODM_RTL8821) && (pDM_Odm->CutVersion == ODM_CUT_A)) + bCtlLdpc = TRUE; + else if( pDM_Odm->SupportICType == ODM_RTL8812 && + IOTPeer == HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP) + bCtlLdpc = TRUE; + + if(bCtlLdpc) + { + if(UndecoratedSmoothedPWDB < (pRA->LdpcThres-5)) + MgntSet_TX_LDPC(pAdapter, mMacId, TRUE); + else if(UndecoratedSmoothedPWDB > pRA->LdpcThres) + MgntSet_TX_LDPC(pAdapter, mMacId, FALSE); + } + + if(UndecoratedSmoothedPWDB < (pRA->RtsThres-5)) + pRA->bLowerRtsRate = TRUE; + else if(UndecoratedSmoothedPWDB > pRA->RtsThres) + pRA->bLowerRtsRate = FALSE; +} +#endif + + +VOID +odm_RefreshRateAdaptiveMaskMP( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER pAdapter = pDM_Odm->Adapter; + PADAPTER pTargetAdapter = NULL; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMGNT_INFO pMgntInfo = GetDefaultMgntInfo(pAdapter); + + if(pAdapter->bDriverStopped) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, ("<---- odm_RefreshRateAdaptiveMask(): driver is going to unload\n")); + return; + } + + if(!pHalData->bUseRAMask) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("<---- odm_RefreshRateAdaptiveMask(): driver does not control rate adaptive mask\n")); + return; + } + + // if default port is connected, update RA table for default port (infrastructure mode only) + if(pMgntInfo->mAssoc && (!ACTING_AS_AP(pAdapter))) + { + odm_RefreshLdpcRtsMP(pAdapter, pDM_Odm, pMgntInfo->mMacId, pMgntInfo->IOTPeer, pHalData->UndecoratedSmoothedPWDB); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_RefreshRateAdaptiveMask(): Infrasture Mode\n")); + if( ODM_RAStateCheck(pDM_Odm, pHalData->UndecoratedSmoothedPWDB, pMgntInfo->bSetTXPowerTrainingByOid, &pMgntInfo->Ratr_State) ) + { + ODM_PRINT_ADDR(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Target AP addr : "), pMgntInfo->Bssid); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI:%d, RSSI_LEVEL:%d\n", pHalData->UndecoratedSmoothedPWDB, pMgntInfo->Ratr_State)); + pAdapter->HalFunc.UpdateHalRAMaskHandler(pAdapter, pMgntInfo->mMacId, NULL, pMgntInfo->Ratr_State); + } + else if(pDM_Odm->bChangeState) + { + ODM_PRINT_ADDR(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Target AP addr : "), pMgntInfo->Bssid); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Change Power Training State, bDisablePowerTraining = %d\n", pDM_Odm->bDisablePowerTraining)); + pAdapter->HalFunc.UpdateHalRAMaskHandler(pAdapter, pMgntInfo->mMacId, NULL, pMgntInfo->Ratr_State); + } + } + + // + // The following part configure AP/VWifi/IBSS rate adaptive mask. + // + + if(pMgntInfo->mIbss) // Target: AP/IBSS peer. + pTargetAdapter = GetDefaultAdapter(pAdapter); + else + pTargetAdapter = GetFirstAPAdapter(pAdapter); + + // if extension port (softap) is started, updaet RA table for more than one clients associate + if(pTargetAdapter != NULL) + { + int i; + PRT_WLAN_STA pEntry; + + for(i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) + { + pEntry = AsocEntry_EnumStation(pTargetAdapter, i); + if(NULL != pEntry) + { + if(pEntry->bAssociated) + { + odm_RefreshLdpcRtsMP(pAdapter, pDM_Odm, pEntry->AssociatedMacId, pEntry->IOTPeer, pEntry->rssi_stat.UndecoratedSmoothedPWDB); + + if(ODM_RAStateCheck(pDM_Odm, pEntry->rssi_stat.UndecoratedSmoothedPWDB, pMgntInfo->bSetTXPowerTrainingByOid, &pEntry->Ratr_State) ) + { + ODM_PRINT_ADDR(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Target STA addr : "), pEntry->MacAddr); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI:%d, RSSI_LEVEL:%d\n", pEntry->rssi_stat.UndecoratedSmoothedPWDB, pEntry->Ratr_State)); + pAdapter->HalFunc.UpdateHalRAMaskHandler(pTargetAdapter, pEntry->AssociatedMacId, pEntry, pEntry->Ratr_State); + } + else if(pDM_Odm->bChangeState) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Change Power Training State, bDisablePowerTraining = %d\n", pDM_Odm->bDisablePowerTraining)); + pAdapter->HalFunc.UpdateHalRAMaskHandler(pAdapter, pMgntInfo->mMacId, NULL, pMgntInfo->Ratr_State); + } + } + } + } + } + + if(pMgntInfo->bSetTXPowerTrainingByOid) + pMgntInfo->bSetTXPowerTrainingByOid = FALSE; +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +} + + +VOID +odm_RefreshRateAdaptiveMaskCE( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i; + PADAPTER pAdapter = pDM_Odm->Adapter; + PODM_RATE_ADAPTIVE pRA = &pDM_Odm->RateAdaptive; + + if(pAdapter->bDriverStopped) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, ("<---- odm_RefreshRateAdaptiveMask(): driver is going to unload\n")); + return; + } + + if(!pDM_Odm->bUseRAMask) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("<---- odm_RefreshRateAdaptiveMask(): driver does not control rate adaptive mask\n")); + return; + } + + //printk("==> %s \n",__FUNCTION__); + + for(i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pstat) ) { + if(IS_MCAST( pstat->hwaddr)) //if(psta->mac_id ==1) + continue; + if(IS_MCAST( pstat->hwaddr)) + continue; + + #if((RTL8812A_SUPPORT==1)||(RTL8821A_SUPPORT==1)) + if((pDM_Odm->SupportICType == ODM_RTL8812)||(pDM_Odm->SupportICType == ODM_RTL8821)) + { + if(pstat->rssi_stat.UndecoratedSmoothedPWDB < pRA->LdpcThres) + { + pRA->bUseLdpc = TRUE; + pRA->bLowerRtsRate = TRUE; + if((pDM_Odm->SupportICType == ODM_RTL8821) && (pDM_Odm->CutVersion == ODM_CUT_A)) + Set_RA_LDPC_8812(pstat, TRUE); + //DbgPrint("RSSI=%d, bUseLdpc = TRUE\n", pHalData->UndecoratedSmoothedPWDB); + } + else if(pstat->rssi_stat.UndecoratedSmoothedPWDB > (pRA->LdpcThres-5)) + { + pRA->bUseLdpc = FALSE; + pRA->bLowerRtsRate = FALSE; + if((pDM_Odm->SupportICType == ODM_RTL8821) && (pDM_Odm->CutVersion == ODM_CUT_A)) + Set_RA_LDPC_8812(pstat, FALSE); + //DbgPrint("RSSI=%d, bUseLdpc = FALSE\n", pHalData->UndecoratedSmoothedPWDB); + } + } + #endif + + if( TRUE == ODM_RAStateCheck(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, FALSE , &pstat->rssi_level) ) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI:%d, RSSI_LEVEL:%d\n", pstat->rssi_stat.UndecoratedSmoothedPWDB, pstat->rssi_level)); + //printk("RSSI:%d, RSSI_LEVEL:%d\n", pstat->rssi_stat.UndecoratedSmoothedPWDB, pstat->rssi_level); + rtw_hal_update_ra_mask(pstat, pstat->rssi_level); + } + else if(pDM_Odm->bChangeState) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Change Power Training State, bDisablePowerTraining = %d\n", pDM_Odm->bDisablePowerTraining)); + rtw_hal_update_ra_mask(pstat, pstat->rssi_level); + } + + } + } + +#endif +} + +VOID +odm_RefreshRateAdaptiveMaskAPADSL( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + struct rtl8192cd_priv *priv = pDM_Odm->priv; + struct aid_obj *aidarray; + u4Byte i; + PSTA_INFO_T pstat; + + if(priv->up_time % 2) + return; + + for(i=0; ipODM_StaInfo[i]; + + if(IS_STA_VALID(pstat) ) + { +#if defined(UNIVERSAL_REPEATER) || defined(MBSSID) + aidarray = container_of(pstat, struct aid_obj, station); + priv = aidarray->priv; +#endif + + if (!priv->pmib->dot11StationConfigEntry.autoRate) + continue; + + if(ODM_RAStateCheck(pDM_Odm, (s4Byte)pstat->rssi, FALSE, &pstat->rssi_level) ) { + ODM_PRINT_ADDR(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Target STA addr : "), pstat->hwaddr); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI:%d, RSSI_LEVEL:%d\n", pstat->rssi, pstat->rssi_level)); + +#if defined(CONFIG_PCI_HCI) +#ifdef CONFIG_WLAN_HAL + if (IS_HAL_CHIP(priv)) { +#ifdef WDS + if(!(pstat->state & WIFI_WDS))//if WDS donot setting +#endif + GET_HAL_INTERFACE(priv)->UpdateHalRAMaskHandler(priv, pstat, pstat->rssi_level); + } else +#endif +#ifdef CONFIG_RTL_8812_SUPPORT + if(GET_CHIP_VER(priv)== VERSION_8812E) { + UpdateHalRAMask8812(priv, pstat, 3); + } else +#endif +#ifdef CONFIG_RTL_88E_SUPPORT + if (GET_CHIP_VER(priv)==VERSION_8188E) { +#ifdef TXREPORT + add_RATid(priv, pstat); +#endif + } else +#endif + { +#if defined(CONFIG_RTL_92D_SUPPORT) || defined(CONFIG_RTL_92C_SUPPORT) + add_update_RATid(priv, pstat); +#endif + } +#elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + update_STA_RATid(priv, pstat); +#endif + } + } + } +#endif +} + + +// Return Value: BOOLEAN +// - TRUE: RATRState is changed. +BOOLEAN +ODM_RAStateCheck( + IN PVOID pDM_VOID, + IN s4Byte RSSI, + IN BOOLEAN bForceUpdate, + OUT pu1Byte pRATRState + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_RATE_ADAPTIVE pRA = &pDM_Odm->RateAdaptive; + const u1Byte GoUpGap = 5; + u1Byte HighRSSIThreshForRA = pRA->HighRSSIThresh; + u1Byte LowRSSIThreshForRA = pRA->LowRSSIThresh; + u1Byte RATRState; + + // Threshold Adjustment: + // when RSSI state trends to go up one or two levels, make sure RSSI is high enough. + // Here GoUpGap is added to solve the boundary's level alternation issue. +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + u1Byte UltraLowRSSIThreshForRA = pRA->UltraLowRSSIThresh; + if(pDM_Odm->SupportICType == ODM_RTL8881A) + LowRSSIThreshForRA = 30; // for LDPC / BCC switch +#endif + + switch (*pRATRState) + { + case DM_RATR_STA_INIT: + case DM_RATR_STA_HIGH: + break; + + case DM_RATR_STA_MIDDLE: + HighRSSIThreshForRA += GoUpGap; + break; + + case DM_RATR_STA_LOW: + HighRSSIThreshForRA += GoUpGap; + LowRSSIThreshForRA += GoUpGap; + break; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + case DM_RATR_STA_ULTRA_LOW: + HighRSSIThreshForRA += GoUpGap; + LowRSSIThreshForRA += GoUpGap; + UltraLowRSSIThreshForRA += GoUpGap; + break; +#endif + + default: + ODM_RT_ASSERT(pDM_Odm, FALSE, ("wrong rssi level setting %d !", *pRATRState) ); + break; + } + + // Decide RATRState by RSSI. + if(RSSI > HighRSSIThreshForRA) + RATRState = DM_RATR_STA_HIGH; + else if(RSSI > LowRSSIThreshForRA) + RATRState = DM_RATR_STA_MIDDLE; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + else if(RSSI > UltraLowRSSIThreshForRA) + RATRState = DM_RATR_STA_LOW; + else + RATRState = DM_RATR_STA_ULTRA_LOW; +#else + else + RATRState = DM_RATR_STA_LOW; +#endif + //printk("==>%s,RATRState:0x%02x ,RSSI:%d \n",__FUNCTION__,RATRState,RSSI); + + if( *pRATRState!=RATRState || bForceUpdate) + { + ODM_RT_TRACE( pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI Level %d -> %d\n", *pRATRState, RATRState) ); + *pRATRState = RATRState; + return TRUE; + } + + return FALSE; +} + +VOID +odm_RefreshBasicRateMask( + IN PVOID pDM_VOID + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + static u1Byte Stage = 0; + u1Byte CurStage = 0; + OCTET_STRING osRateSet; + PMGNT_INFO pMgntInfo = GetDefaultMgntInfo(Adapter); + u1Byte RateSet[5] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M, MGN_6M}; + + if(pDM_Odm->SupportICType != ODM_RTL8812 && pDM_Odm->SupportICType != ODM_RTL8821 ) + return; + + if(pDM_Odm->bLinked == FALSE) // unlink Default port information + CurStage = 0; + else if(pDM_Odm->RSSI_Min < 40) // link RSSI < 40% + CurStage = 1; + else if(pDM_Odm->RSSI_Min > 45) // link RSSI > 45% + CurStage = 3; + else + CurStage = 2; // link 25% <= RSSI <= 30% + + if(CurStage != Stage) + { + if(CurStage == 1) + { + FillOctetString(osRateSet, RateSet, 5); + FilterSupportRate(pMgntInfo->mBrates, &osRateSet, FALSE); + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_BASIC_RATE, (pu1Byte)&osRateSet); + } + else if(CurStage == 3 && (Stage == 1 || Stage == 2)) + { + Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) ); + } + } + + Stage = CurStage; +#endif +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_DynamicARFBSelect( + IN PVOID pDM_VOID, + IN u1Byte rate, + IN BOOLEAN Collision_State +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + + if(pDM_Odm->SupportICType != ODM_RTL8192E) + return; + + if(Collision_State == pRA_Table->PT_collision_pre) + return; + + if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS12){ + if (Collision_State == 1){ + if(rate == DESC_RATEMCS12){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x0); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x07060501); + } + else if(rate == DESC_RATEMCS11){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x0); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x07070605); + } + else if(rate == DESC_RATEMCS10){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x0); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x08080706); + } + else if(rate == DESC_RATEMCS9){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x0); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x08080707); + } + else{ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x0); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x09090808); + } + } + else{ // Collision_State == 0 + if(rate == DESC_RATEMCS12){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x05010000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x09080706); + } + else if(rate == DESC_RATEMCS11){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x06050000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x09080807); + } + else if(rate == DESC_RATEMCS10){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x07060000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x0a090908); + } + else if(rate == DESC_RATEMCS9){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x07070000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x0a090808); + } + else{ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x08080000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x0b0a0909); + } + } + } + else{ // MCS13~MCS15, 1SS, G-mode + if (Collision_State == 1){ + if(rate == DESC_RATEMCS15){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x00000000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x05040302); + } + else if(rate == DESC_RATEMCS14){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x00000000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x06050302); + } + else if(rate == DESC_RATEMCS13){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x00000000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x07060502); + } + else{ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x00000000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x06050402); + } + } + else{ // Collision_State == 0 + if(rate == DESC_RATEMCS15){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x03020000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x07060504); + } + else if(rate == DESC_RATEMCS14){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x03020000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x08070605); + } + else if(rate == DESC_RATEMCS13){ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x05020000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x09080706); + } + else{ + + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E, 0x04020000); + ODM_Write4Byte(pDM_Odm, REG_DARFRC_8192E+4, 0x08070605); + } + + + } + + } + pRA_Table->PT_collision_pre = Collision_State; +} + +VOID +ODM_RateAdaptiveStateApInit( + IN PVOID PADAPTER_VOID, + IN PRT_WLAN_STA pEntry + ) +{ + PADAPTER Adapter = (PADAPTER)PADAPTER_VOID; + pEntry->Ratr_State = DM_RATR_STA_INIT; +} +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +u4Byte +ODM_Get_Rate_Bitmap( + IN PVOID pDM_VOID, + IN u4Byte macid, + IN u4Byte ra_mask, + IN u1Byte rssi_level + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PSTA_INFO_T pEntry; + u4Byte rate_bitmap = 0; + u1Byte WirelessMode; + //u1Byte WirelessMode =*(pDM_Odm->pWirelessMode); + + + pEntry = pDM_Odm->pODM_StaInfo[macid]; + if(!IS_STA_VALID(pEntry)) + return ra_mask; + + WirelessMode = pEntry->wireless_mode; + + switch(WirelessMode) + { + case ODM_WM_B: + if(ra_mask & 0x0000000c) //11M or 5.5M enable + rate_bitmap = 0x0000000d; + else + rate_bitmap = 0x0000000f; + break; + + case (ODM_WM_G): + case (ODM_WM_A): + if(rssi_level == DM_RATR_STA_HIGH) + rate_bitmap = 0x00000f00; + else + rate_bitmap = 0x00000ff0; + break; + + case (ODM_WM_B|ODM_WM_G): + if(rssi_level == DM_RATR_STA_HIGH) + rate_bitmap = 0x00000f00; + else if(rssi_level == DM_RATR_STA_MIDDLE) + rate_bitmap = 0x00000ff0; + else + rate_bitmap = 0x00000ff5; + break; + + case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G) : + case (ODM_WM_B|ODM_WM_N24G) : + case (ODM_WM_G|ODM_WM_N24G) : + case (ODM_WM_A|ODM_WM_N5G) : + { + if ( pDM_Odm->RFType == ODM_1T2R ||pDM_Odm->RFType == ODM_1T1R) + { + if(rssi_level == DM_RATR_STA_HIGH) + { + rate_bitmap = 0x000f0000; + } + else if(rssi_level == DM_RATR_STA_MIDDLE) + { + rate_bitmap = 0x000ff000; + } + else{ + if (*(pDM_Odm->pBandWidth) == ODM_BW40M) + rate_bitmap = 0x000ff015; + else + rate_bitmap = 0x000ff005; + } + } + else + { + if(rssi_level == DM_RATR_STA_HIGH) + { + rate_bitmap = 0x0f8f0000; + } + else if(rssi_level == DM_RATR_STA_MIDDLE) + { + rate_bitmap = 0x0f8ff000; + } + else + { + if (*(pDM_Odm->pBandWidth) == ODM_BW40M) + rate_bitmap = 0x0f8ff015; + else + rate_bitmap = 0x0f8ff005; + } + } + } + break; + + case (ODM_WM_AC|ODM_WM_G): + if(rssi_level == 1) + rate_bitmap = 0xfc3f0000; + else if(rssi_level == 2) + rate_bitmap = 0xfffff000; + else + rate_bitmap = 0xffffffff; + break; + + case (ODM_WM_AC|ODM_WM_A): + + if (pDM_Odm->RFType == RF_1T1R) + { + if(rssi_level == 1) // add by Gary for ac-series + rate_bitmap = 0x003f8000; + else if (rssi_level == 2) + rate_bitmap = 0x003ff000; + else + rate_bitmap = 0x003ff010; + } + else + { + if(rssi_level == 1) // add by Gary for ac-series + rate_bitmap = 0xfe3f8000; // VHT 2SS MCS3~9 + else if (rssi_level == 2) + rate_bitmap = 0xfffff000; // VHT 2SS MCS0~9 + else + rate_bitmap = 0xfffff010; // All + } + break; + + default: + if(pDM_Odm->RFType == RF_1T2R) + rate_bitmap = 0x000fffff; + else + rate_bitmap = 0x0fffffff; + break; + + } + + //printk("%s ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n",__FUNCTION__,rssi_level,WirelessMode,rate_bitmap); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, (" ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n",rssi_level,WirelessMode,rate_bitmap)); + + return (ra_mask&rate_bitmap); + +} + +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_CE) \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RaInfo.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RaInfo.h new file mode 100755 index 000000000000..b9625de98dd0 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RaInfo.h @@ -0,0 +1,167 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMRAINFO_H__ +#define __PHYDMRAINFO_H__ + +#define RAINFO_VERSION "1.0" + +#define AP_InitRateAdaptiveState ODM_RateAdaptiveStateApInit + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#define DM_RATR_STA_ULTRA_LOW 4 +#endif + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +typedef struct _Rate_Adaptive_Table_{ + u1Byte firstconnect; + #if(DM_ODM_SUPPORT_TYPE==ODM_WIN) + BOOLEAN PT_collision_pre; + #endif +}RA_T, *pRA_T; +#endif + +typedef struct _ODM_RATE_ADAPTIVE +{ + u1Byte Type; // DM_Type_ByFW/DM_Type_ByDriver + u1Byte HighRSSIThresh; // if RSSI > HighRSSIThresh => RATRState is DM_RATR_STA_HIGH + u1Byte LowRSSIThresh; // if RSSI <= LowRSSIThresh => RATRState is DM_RATR_STA_LOW + u1Byte RATRState; // Current RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW + + #if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + u1Byte LdpcThres; // if RSSI > LdpcThres => switch from LPDC to BCC + BOOLEAN bLowerRtsRate; + #endif + + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + u1Byte RtsThres; + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + BOOLEAN bUseLdpc; + #else + u1Byte UltraLowRSSIThresh; + u4Byte LastRATR; // RATR Register Content + #endif + +} ODM_RATE_ADAPTIVE, *PODM_RATE_ADAPTIVE; + +VOID +odm_RSSIMonitorInit( + IN PVOID pDM_VOID + ); + +VOID +odm_RSSIMonitorCheck( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE==ODM_WIN) +VOID +odm_RSSIDumpToRegister( + IN PVOID pDM_VOID + ); +#endif + +VOID +odm_RSSIMonitorCheckMP( + IN PVOID pDM_VOID + ); + +VOID +odm_RSSIMonitorCheckCE( + IN PVOID pDM_VOID + ); + +VOID +odm_RSSIMonitorCheckAP( + IN PVOID pDM_VOID + ); + + +VOID +odm_RateAdaptiveMaskInit( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMask( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMaskMP( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMaskCE( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMaskAPADSL( + IN PVOID pDM_VOID + ); + +BOOLEAN +ODM_RAStateCheck( + IN PVOID pDM_VOID, + IN s4Byte RSSI, + IN BOOLEAN bForceUpdate, + OUT pu1Byte pRATRState + ); + +VOID +odm_RefreshBasicRateMask( + IN PVOID pDM_VOID + ); + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_DynamicARFBSelect( + IN PVOID pDM_VOID, + IN u1Byte rate, + IN BOOLEAN Collision_State + ); + +VOID +ODM_RateAdaptiveStateApInit( + IN PVOID PADAPTER_VOID, + IN PRT_WLAN_STA pEntry + ); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +u4Byte +ODM_Get_Rate_Bitmap( + IN PVOID pDM_VOID, + IN u4Byte macid, + IN u4Byte ra_mask, + IN u1Byte rssi_level + ); +#endif + +#endif //#ifndef __ODMRAINFO_H__ + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RegDefine11AC.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RegDefine11AC.h new file mode 100755 index 000000000000..e7e54184f099 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RegDefine11AC.h @@ -0,0 +1,76 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __ODM_REGDEFINE11AC_H__ +#define __ODM_REGDEFINE11AC_H__ + +//2 RF REG LIST + + + +//2 BB REG LIST +//PAGE 8 +#define ODM_REG_CCK_RPT_FORMAT_11AC 0x804 +#define ODM_REG_BB_RX_PATH_11AC 0x808 +#define ODM_REG_BB_ATC_11AC 0x860 +#define ODM_REG_DBG_RPT_11AC 0x8fc +//PAGE 9 +#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 +#define ODM_REG_NHM_TIMER_11AC 0x990 +#define ODM_REG_NHM_TH9_TH10_11AC 0x994 +#define ODM_REG_NHM_TH3_TO_TH0_11AC 0x998 +#define ODM_REG_NHM_TH7_TO_TH4_11AC 0x99c +#define ODM_REG_NHM_TH8_11AC 0x9a0 +#define ODM_REG_NHM_9E8_11AC 0x9e8 +//PAGE A +#define ODM_REG_CCK_CCA_11AC 0xA0A +#define ODM_REG_CCK_FA_RST_11AC 0xA2C +#define ODM_REG_CCK_FA_11AC 0xA5C +//PAGE B +#define ODM_REG_RST_RPT_11AC 0xB58 +//PAGE C +#define ODM_REG_TRMUX_11AC 0xC08 +#define ODM_REG_IGI_A_11AC 0xC50 +//PAGE E +#define ODM_REG_IGI_B_11AC 0xE50 +#define ODM_REG_TRMUX_11AC_B 0xE08 +//PAGE F +#define ODM_REG_CCK_CCA_CNT_11AC 0xF08 +#define ODM_REG_OFDM_FA_11AC 0xF48 +#define ODM_REG_RPT_11AC 0xfa0 +#define ODM_REG_NHM_CNT_11AC 0xfa8 +//PAGE 18 +#define ODM_REG_IGI_C_11AC 0x1850 +//PAGE 1A +#define ODM_REG_IGI_D_11AC 0x1A50 + +//2 MAC REG LIST +#define ODM_REG_RESP_TX_11AC 0x6D8 + + + +//DIG Related +#define ODM_BIT_IGI_11AC 0xFFFFFFFF +#define ODM_BIT_CCK_RPT_FORMAT_11AC BIT16 +#define ODM_BIT_BB_RX_PATH_11AC 0xF +#define ODM_BIT_BB_ATC_11AC BIT14 + +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RegDefine11N.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RegDefine11N.h new file mode 100755 index 000000000000..9d07509f6feb --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_RegDefine11N.h @@ -0,0 +1,181 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __ODM_REGDEFINE11N_H__ +#define __ODM_REGDEFINE11N_H__ + + +//2 RF REG LIST +#define ODM_REG_RF_MODE_11N 0x00 +#define ODM_REG_RF_0B_11N 0x0B +#define ODM_REG_CHNBW_11N 0x18 +#define ODM_REG_T_METER_11N 0x24 +#define ODM_REG_RF_25_11N 0x25 +#define ODM_REG_RF_26_11N 0x26 +#define ODM_REG_RF_27_11N 0x27 +#define ODM_REG_RF_2B_11N 0x2B +#define ODM_REG_RF_2C_11N 0x2C +#define ODM_REG_RXRF_A3_11N 0x3C +#define ODM_REG_T_METER_92D_11N 0x42 +#define ODM_REG_T_METER_88E_11N 0x42 + + + +//2 BB REG LIST +//PAGE 8 +#define ODM_REG_BB_CTRL_11N 0x800 +#define ODM_REG_RF_PIN_11N 0x804 +#define ODM_REG_PSD_CTRL_11N 0x808 +#define ODM_REG_TX_ANT_CTRL_11N 0x80C +#define ODM_REG_BB_PWR_SAV5_11N 0x818 +#define ODM_REG_CCK_RPT_FORMAT_11N 0x824 +#define ODM_REG_CCK_RPT_FORMAT_11N_B 0x82C +#define ODM_REG_RX_DEFUALT_A_11N 0x858 +#define ODM_REG_RX_DEFUALT_B_11N 0x85A +#define ODM_REG_BB_PWR_SAV3_11N 0x85C +#define ODM_REG_ANTSEL_CTRL_11N 0x860 +#define ODM_REG_RX_ANT_CTRL_11N 0x864 +#define ODM_REG_PIN_CTRL_11N 0x870 +#define ODM_REG_BB_PWR_SAV1_11N 0x874 +#define ODM_REG_ANTSEL_PATH_11N 0x878 +#define ODM_REG_BB_3WIRE_11N 0x88C +#define ODM_REG_SC_CNT_11N 0x8C4 +#define ODM_REG_PSD_DATA_11N 0x8B4 +#define ODM_REG_PSD_DATA_11N 0x8B4 +#define ODM_REG_NHM_TIMER_11N 0x894 +#define ODM_REG_NHM_TH9_TH10_11N 0x890 +#define ODM_REG_NHM_TH3_TO_TH0_11N 0x898 +#define ODM_REG_NHM_TH7_TO_TH4_11N 0x89c +#define ODM_REG_NHM_CNT_11N 0x8d8 +//PAGE 9 +#define ODM_REG_DBG_RPT_11N 0x908 +#define ODM_REG_ANT_MAPPING1_11N 0x914 +#define ODM_REG_ANT_MAPPING2_11N 0x918 +//PAGE A +#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define ODM_REG_CCK_CCA_11N 0xA0A +#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define ODM_REG_CCK_FA_RST_11N 0xA2C +#define ODM_REG_CCK_FA_MSB_11N 0xA58 +#define ODM_REG_CCK_FA_LSB_11N 0xA5C +#define ODM_REG_CCK_CCA_CNT_11N 0xA60 +#define ODM_REG_BB_PWR_SAV4_11N 0xA74 +//PAGE B +#define ODM_REG_LNA_SWITCH_11N 0xB2C +#define ODM_REG_PATH_SWITCH_11N 0xB30 +#define ODM_REG_RSSI_CTRL_11N 0xB38 +#define ODM_REG_CONFIG_ANTA_11N 0xB68 +#define ODM_REG_RSSI_BT_11N 0xB9C +//PAGE C +#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define ODM_REG_BB_RX_PATH_11N 0xC04 +#define ODM_REG_TRMUX_11N 0xC08 +#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C +#define ODM_REG_RXIQI_MATRIX_11N 0xC14 +#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define ODM_REG_IGI_A_11N 0xC50 +#define ODM_REG_ANTDIV_PARA2_11N 0xC54 +#define ODM_REG_IGI_B_11N 0xC58 +#define ODM_REG_ANTDIV_PARA3_11N 0xC5C +#define ODM_REG_L1SBD_PD_CH_11N 0XC6C +#define ODM_REG_BB_PWR_SAV2_11N 0xC70 +#define ODM_REG_RX_OFF_11N 0xC7C +#define ODM_REG_TXIQK_MATRIXA_11N 0xC80 +#define ODM_REG_TXIQK_MATRIXB_11N 0xC88 +#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define ODM_REG_ANTDIV_PARA1_11N 0xCA4 +#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0 +//PAGE D +#define ODM_REG_OFDM_FA_RSTD_11N 0xD00 +#define ODM_REG_BB_ATC_11N 0xD2C +#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8 +#define ODM_REG_RPT_11N 0xDF4 +//PAGE E +#define ODM_REG_TXAGC_A_6_18_11N 0xE00 +#define ODM_REG_TXAGC_A_24_54_11N 0xE04 +#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define ODM_REG_FPGA0_IQK_11N 0xE28 +#define ODM_REG_TXIQK_TONE_A_11N 0xE30 +#define ODM_REG_RXIQK_TONE_A_11N 0xE34 +#define ODM_REG_TXIQK_PI_A_11N 0xE38 +#define ODM_REG_RXIQK_PI_A_11N 0xE3C +#define ODM_REG_TXIQK_11N 0xE40 +#define ODM_REG_RXIQK_11N 0xE44 +#define ODM_REG_IQK_AGC_PTS_11N 0xE48 +#define ODM_REG_IQK_AGC_RSP_11N 0xE4C +#define ODM_REG_BLUETOOTH_11N 0xE6C +#define ODM_REG_RX_WAIT_CCA_11N 0xE70 +#define ODM_REG_TX_CCK_RFON_11N 0xE74 +#define ODM_REG_TX_CCK_BBON_11N 0xE78 +#define ODM_REG_OFDM_RFON_11N 0xE7C +#define ODM_REG_OFDM_BBON_11N 0xE80 +#define ODM_REG_TX2RX_11N 0xE84 +#define ODM_REG_TX2TX_11N 0xE88 +#define ODM_REG_RX_CCK_11N 0xE8C +#define ODM_REG_RX_OFDM_11N 0xED0 +#define ODM_REG_RX_WAIT_RIFS_11N 0xED4 +#define ODM_REG_RX2RX_11N 0xED8 +#define ODM_REG_STANDBY_11N 0xEDC +#define ODM_REG_SLEEP_11N 0xEE0 +#define ODM_REG_PMPD_ANAEN_11N 0xEEC +#define ODM_REG_IGI_C_11N 0xF84 +#define ODM_REG_IGI_D_11N 0xF88 + +//2 MAC REG LIST +#define ODM_REG_BB_RST_11N 0x02 +#define ODM_REG_ANTSEL_PIN_11N 0x4C +#define ODM_REG_EARLY_MODE_11N 0x4D0 +#define ODM_REG_RSSI_MONITOR_11N 0x4FE +#define ODM_REG_EDCA_VO_11N 0x500 +#define ODM_REG_EDCA_VI_11N 0x504 +#define ODM_REG_EDCA_BE_11N 0x508 +#define ODM_REG_EDCA_BK_11N 0x50C +#define ODM_REG_TXPAUSE_11N 0x522 +#define ODM_REG_RESP_TX_11N 0x6D8 +#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + + +//DIG Related +#define ODM_BIT_IGI_11N 0x0000007F +#define ODM_BIT_CCK_RPT_FORMAT_11N BIT9 +#define ODM_BIT_BB_RX_PATH_11N 0xF +#define ODM_BIT_BB_ATC_11N BIT11 + +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_debug.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_debug.c new file mode 100755 index 000000000000..7e514db3b609 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_debug.c @@ -0,0 +1,873 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ + +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + + +VOID +PHYDM_InitDebugSetting( + IN PDM_ODM_T pDM_Odm + ) +{ +pDM_Odm->DebugLevel = ODM_DBG_TRACE; + +pDM_Odm->DebugComponents = +\ +#if DBG +//BB Functions +// ODM_COMP_DIG | +// ODM_COMP_RA_MASK | +// ODM_COMP_DYNAMIC_TXPWR | +// ODM_COMP_FA_CNT | +// ODM_COMP_RSSI_MONITOR | +// ODM_COMP_CCK_PD | +// ODM_COMP_ANT_DIV | +// ODM_COMP_PWR_SAVE | +// ODM_COMP_PWR_TRAIN | +// ODM_COMP_RATE_ADAPTIVE | +// ODM_COMP_PATH_DIV | +// ODM_COMP_DYNAMIC_PRICCA | +// ODM_COMP_RXHP | +// ODM_COMP_MP | +// ODM_COMP_CFO_TRACKING | +// ODM_COMP_ACS | +// PHYDM_COMP_ADAPTIVITY | + +//MAC Functions +// ODM_COMP_EDCA_TURBO | +// ODM_COMP_EARLY_MODE | +//RF Functions +// ODM_COMP_TX_PWR_TRACK | +// ODM_COMP_RX_GAIN_TRACK | +// ODM_COMP_CALIBRATION | +//Common +// ODM_COMP_COMMON | +// ODM_COMP_INIT | +// ODM_COMP_PSD | +#endif + 0; +} + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + +static u1Byte BbDbgBuf[BB_TMP_BUF_SIZE]; +VOID +phydm_BB_Debug_Info(IN PDM_ODM_T pDM_Odm) +{ + + u1Byte RX_HT_BW, RX_VHT_BW, RXSC, RX_HT, RX_BW; + static u1Byte vRX_BW ; + u4Byte value32, value32_1, value32_2, value32_3; + s4Byte SFO_A, SFO_B, SFO_C, SFO_D; + s4Byte LFO_A, LFO_B, LFO_C, LFO_D; + static u1Byte MCSS,Tail,Parity,rsv,vrsv,idx,smooth,htsound,agg,stbc,vstbc,fec,fecext,sgi,sgiext,htltf,vgid,vNsts,vtxops,vrsv2,vbrsv,bf,vbcrc; + static u2Byte HLength,htcrc8,Length; + static u2Byte vpaid; + static u2Byte vLength,vhtcrc8,vMCSS,vTail,vbTail; + static u1Byte HMCSS,HRX_BW; + + + u1Byte pwDB; + s1Byte RXEVM_0, RXEVM_1, RXEVM_2 ; + u1Byte RF_gain_pathA, RF_gain_pathB, RF_gain_pathC, RF_gain_pathD; + u1Byte RX_SNR_pathA, RX_SNR_pathB, RX_SNR_pathC, RX_SNR_pathD; + s4Byte sig_power; + const char *RXHT_table[] = {"legacy", "HT", "VHT"}; + const char *BW_table[] = {"20M", "40M", "80M"}; + const char *RXSC_table[] = {"duplicate/full bw", "usc20-1", "lsc20-1", "usc20-2", "lsc20-2", "usc40", "lsc40"}; + + const char *L_rate[]={"6M","9M","12M","18M","24M","36M","48M","54M"}; + + + /* + const double evm_comp_20M = 0.579919469776867; //10*log10(64.0/56.0) + const double evm_comp_40M = 0.503051183113957; //10*log10(128.0/114.0) + const double evm_comp_80M = 0.244245993314183; //10*log10(256.0/242.0) + const double evm_comp_160M = 0.244245993314183; //10*log10(512.0/484.0) + */ + + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + return; + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s \n", "BB Report Info"); + DCMD_Printf(BbDbgBuf); + + //BW & Mode Detection + /////////////////////////////////////////////////////// + value32 = ODM_GetBBReg(pDM_Odm, 0xf80 ,bMaskDWord); + value32_2 =value32; + RX_HT_BW = (u1Byte)(value32&0x1) ; + RX_VHT_BW = (u1Byte)((value32>>1)&0x3); + RXSC = (u1Byte)(value32&0x78); + value32_1= (value32&0x180)>>7; + RX_HT = (u1Byte)(value32_1); + /* + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "F80", value32_2); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_HT_BW", RX_HT_BW); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_VHT_BW", RX_VHT_BW); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_SC", RXSC); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_HT", RX_HT); + DCMD_Printf(BbDbgBuf); + */ + + //rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n RX_HT:%s ", RXHT_table[RX_HT]); + //DCMD_Printf(BbDbgBuf); + RX_BW = 0; + + if(RX_HT == 2) + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Mode: VHT Mode"); + DCMD_Printf(BbDbgBuf); + if(RX_VHT_BW==0) + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " BW=20M"); + DCMD_Printf(BbDbgBuf); + } + else if(RX_VHT_BW==1) + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " BW=40M"); + DCMD_Printf(BbDbgBuf); + } + else + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " BW=80M"); + DCMD_Printf(BbDbgBuf); + } + RX_BW = RX_VHT_BW; + } + else if(RX_HT == 1) + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Mode: HT Mode"); + DCMD_Printf(BbDbgBuf); + if(RX_HT_BW==0) + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " BW=20M"); + DCMD_Printf(BbDbgBuf); + } + else if(RX_HT_BW==1) + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " BW=40M"); + DCMD_Printf(BbDbgBuf); + } + RX_BW = RX_HT_BW; + } + else + { + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Mode: Legeacy Mode"); + DCMD_Printf(BbDbgBuf); + } + + if(RX_HT !=0) + { + if(RXSC==0) + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n duplicate/full bw"); + else if(RXSC==1) + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n usc20-1"); + else if(RXSC==2) + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n lsc20-1"); + else if(RXSC==3) + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n usc20-2"); + else if(RXSC==4) + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n lsc20-2"); + else if(RXSC==9) + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n usc40"); + else if(RXSC==10) + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n lsc40"); + DCMD_Printf(BbDbgBuf); + } + /* + if(RX_HT == 2){ + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " BW:%s", BW_table[RX_VHT_BW]); + RX_BW = RX_VHT_BW; + } + else if(RX_HT == 1){ + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " BW:%s", BW_table[RX_HT_BW]); + RX_BW = RX_HT_BW; + } + else + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, ""); + + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, " RXSC:%s", RXSC_table[RXSC]); + DCMD_Printf(BbDbgBuf); + */ + /////////////////////////////////////////////////////// + +// rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "dB Conversion: 10log(65)", ODM_PWdB_Conversion(65,10,0)); +// DCMD_Printf(BbDbgBuf); + + // RX signal power and AGC related info + /////////////////////////////////////////////////////// + value32 = ODM_GetBBReg(pDM_Odm, 0xF90 ,bMaskDWord); + pwDB = (u1Byte) ((value32 & bMaskByte1) >> 8); + pwDB=pwDB>>1; + sig_power = -110+pwDB; + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "OFDM RX Signal Power(dB)", sig_power); + DCMD_Printf(BbDbgBuf); + + + value32 = ODM_GetBBReg(pDM_Odm, 0xd14 ,bMaskDWord); + RX_SNR_pathA = (u1Byte)(value32&0xFF)>>1; + RF_gain_pathA = (s1Byte) ((value32 & bMaskByte1) >> 8); + RF_gain_pathA *=2; + value32 = ODM_GetBBReg(pDM_Odm, 0xd54 ,bMaskDWord); + RX_SNR_pathB = (u1Byte)(value32&0xFF)>>1; + RF_gain_pathB = (s1Byte) ((value32 & bMaskByte1) >> 8); + RF_gain_pathB *=2; + value32 = ODM_GetBBReg(pDM_Odm, 0xd94 ,bMaskDWord); + RX_SNR_pathC = (u1Byte)(value32&0xFF)>>1; + RF_gain_pathC = (s1Byte) ((value32 & bMaskByte1) >> 8); + RF_gain_pathC *=2; + value32 = ODM_GetBBReg(pDM_Odm, 0xdd4 ,bMaskDWord); + RX_SNR_pathD = (u1Byte)(value32&0xFF)>>1; + RF_gain_pathD = (s1Byte) ((value32 & bMaskByte1) >> 8); + RF_gain_pathD *=2; + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "OFDM RX RF Gain(A/B/C/D)", RF_gain_pathA, RF_gain_pathA, RF_gain_pathC, RF_gain_pathD); + DCMD_Printf(BbDbgBuf); + /////////////////////////////////////////////////////// + + // RX Counter related info + /////////////////////////////////////////////////////// + value32 = ODM_GetBBReg(pDM_Odm, 0xF08 ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "OFDM CCA Counter", ((value32&0xFFFF0000)>>16)); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xFD0 ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "OFDM SBD Fail Counter", value32&0xFFFF); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xFC4 ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "VHT SIGA/SIGB CRC8 Fail Counter", value32&0xFFFF, ((value32&0xFFFF0000)>>16)); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xFCC ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "CCK CCA Counter", value32&0xFFFF); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xFBC ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "LSIG (\"Parity Fail\"/\"Rate Illegal\") Counter", value32&0xFFFF, ((value32&0xFFFF0000)>>16)); + DCMD_Printf(BbDbgBuf); + + value32_1 = ODM_GetBBReg(pDM_Odm, 0xFC8 ,bMaskDWord); + value32_2 = ODM_GetBBReg(pDM_Odm, 0xFC0 ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "HT/VHT MCS NOT SUPPORT counter", ((value32_2&0xFFFF0000)>>16), value32_1&0xFFFF); + DCMD_Printf(BbDbgBuf); + /////////////////////////////////////////////////////// + + // PostFFT related info + /////////////////////////////////////////////////////// + + value32 = ODM_GetBBReg(pDM_Odm, 0xF8c ,bMaskDWord); + RXEVM_0 = (s1Byte) ((value32 & bMaskByte2) >> 16); + RXEVM_0 /=2; + if(RXEVM_0 < -63) + RXEVM_0=0; + + DCMD_Printf(BbDbgBuf); + RXEVM_1 = (s1Byte) ((value32 & bMaskByte3) >> 24); + RXEVM_1 /=2; + value32 = ODM_GetBBReg(pDM_Odm, 0xF88 ,bMaskDWord); + RXEVM_2 = (s1Byte) ((value32 & bMaskByte2) >> 16); + RXEVM_2 /=2; + + if(RXEVM_1 < -63) + RXEVM_1=0; + if(RXEVM_2 < -63) + RXEVM_2=0; + + /* + if(RX_BW == 0){ + RXEVM_0 -= evm_comp_20M; + RXEVM_1 -= evm_comp_20M; + RXEVM_2 -= evm_comp_20M; + } + else if(RX_BW == 1){ + RXEVM_0 -= evm_comp_40M; + RXEVM_1 -= evm_comp_40M; + RXEVM_2 -= evm_comp_40M; + } + else if (RX_BW == 2){ + RXEVM_0 -= evm_comp_80M; + RXEVM_1 -= evm_comp_80M; + RXEVM_2 -= evm_comp_80M; + } + */ + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d", "RXEVM (1ss/2ss/3ss)", RXEVM_0, RXEVM_1, RXEVM_2); + DCMD_Printf(BbDbgBuf); + +// value32 = ODM_GetBBReg(pDM_Odm, 0xD14 ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "RXSNR(A/B/C/D, dB)", RX_SNR_pathA, RX_SNR_pathB, RX_SNR_pathC, RX_SNR_pathD); + DCMD_Printf(BbDbgBuf); +// rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "B_RXSNR", (value32&0xFF00)>>9); +// DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xF8C ,bMaskDWord); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "CSI_1st /CSI_2nd", value32&0xFFFF, ((value32&0xFFFF0000)>>16)); + DCMD_Printf(BbDbgBuf); + /////////////////////////////////////////////////////// + + //BW & Mode Detection + + //Reset Page F Counter + ODM_SetBBReg(pDM_Odm, 0xB58 ,BIT0, 1); + ODM_SetBBReg(pDM_Odm, 0xB58 ,BIT0, 0); + + //CFO Report Info + //Short CFO + value32 = ODM_GetBBReg(pDM_Odm, 0xd0c ,bMaskDWord); + value32_1 = ODM_GetBBReg(pDM_Odm, 0xd4c ,bMaskDWord); + value32_2 = ODM_GetBBReg(pDM_Odm, 0xd8c ,bMaskDWord); + value32_3 = ODM_GetBBReg(pDM_Odm, 0xdcc ,bMaskDWord); + + SFO_A=(s4Byte)(value32&bMask12Bits); + SFO_B=(s4Byte)(value32_1&bMask12Bits); + SFO_C=(s4Byte)(value32_2&bMask12Bits); + SFO_D=(s4Byte)(value32_3&bMask12Bits); + + LFO_A=(s4Byte)(value32>>16); + LFO_B=(s4Byte)(value32_1>>16); + LFO_C=(s4Byte)(value32_2>>16); + LFO_D=(s4Byte)(value32_3>>16); + + //SFO 2's to dec + if(SFO_A >2047) + { + SFO_A=SFO_A-4096; + } + SFO_A=(SFO_A*312500)/2048; + + if(SFO_B >2047) + { + SFO_B=SFO_B-4096; + } + SFO_B=(SFO_B*312500)/2048; + if(SFO_C >2047) + { + SFO_C=SFO_C-4096; + } + SFO_C=(SFO_C*312500)/2048; + if(SFO_D >2047) + { + SFO_D=SFO_D-4096; + } + SFO_D=(SFO_D*312500)/2048; + + //LFO 2's to dec + + if(LFO_A >4095) + { + LFO_A=LFO_A-8192; + } + + if(LFO_B >4095) + { + LFO_B=LFO_B-8192; + } + + if(LFO_C>4095) + { + LFO_C=LFO_C-8192; + } + + if(LFO_D >4095) + { + LFO_D=LFO_D-8192; + } + LFO_A=LFO_A*312500/4096; + LFO_B=LFO_B*312500/4096; + LFO_C=LFO_C*312500/4096; + LFO_D=LFO_D*312500/4096; + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "CFO Report Info"); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d/ %d/ %d", " Short CFO(Hz) ", SFO_A,SFO_B,SFO_C,SFO_D); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d/ %d/ %d", " Long CFO(Hz) ", LFO_A,LFO_B,LFO_C,LFO_D); + DCMD_Printf(BbDbgBuf); + + //SCFO + value32 = ODM_GetBBReg(pDM_Odm, 0xd10 ,bMaskDWord); + value32_1 = ODM_GetBBReg(pDM_Odm, 0xd50 ,bMaskDWord); + value32_2 = ODM_GetBBReg(pDM_Odm, 0xd90 ,bMaskDWord); + value32_3 = ODM_GetBBReg(pDM_Odm, 0xdd0 ,bMaskDWord); + + SFO_A=(s4Byte)(value32&0x7ff); + SFO_B=(s4Byte)(value32_1&0x7ff); + SFO_C=(s4Byte)(value32_2&0x7ff); + SFO_D=(s4Byte)(value32_3&0x7ff); + + if(SFO_A >1023) + { + SFO_A=SFO_A-2048; + } + + if(SFO_B >2047) + { + SFO_B=SFO_B-4096; +} + + if(SFO_C >2047) + { + SFO_C=SFO_C-4096; + } + + if(SFO_D >2047) + { + SFO_D=SFO_D-4096; + } + + SFO_A=SFO_A*312500/1024; + SFO_B=SFO_B*312500/1024; + SFO_C=SFO_C*312500/1024; + SFO_D=SFO_D*312500/1024; + + LFO_A=(s4Byte)(value32>>16); + LFO_B=(s4Byte)(value32_1>>16); + LFO_C=(s4Byte)(value32_2>>16); + LFO_D=(s4Byte)(value32_3>>16); + + if(LFO_A >4095) + { + LFO_A=LFO_A-8192; + } + + if(LFO_B >4095) + { + LFO_B=LFO_B-8192; + } + + if(LFO_C>4095) + { + LFO_C=LFO_C-8192; + } + + if(LFO_D >4095) + { + LFO_D=LFO_D-8192; + } + LFO_A=LFO_A*312500/4096; + LFO_B=LFO_B*312500/4096; + LFO_C=LFO_C*312500/4096; + LFO_D=LFO_D*312500/4096; + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d/ %d/ %d", " Value SCFO(Hz) ", SFO_A,SFO_B,SFO_C,SFO_D); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d/ %d/ %d", " ACQ CFO(Hz) ", LFO_A,LFO_B,LFO_C,LFO_D); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xd14 ,bMaskDWord); + value32_1 = ODM_GetBBReg(pDM_Odm, 0xd54 ,bMaskDWord); + value32_2 = ODM_GetBBReg(pDM_Odm, 0xd94 ,bMaskDWord); + value32_3 = ODM_GetBBReg(pDM_Odm, 0xdd4 ,bMaskDWord); + + LFO_A=(s4Byte)(value32>>16); + LFO_B=(s4Byte)(value32_1>>16); + LFO_C=(s4Byte)(value32_2>>16); + LFO_D=(s4Byte)(value32_3>>16); + + if(LFO_A >4095) + { + LFO_A=LFO_A-8192; + } + + if(LFO_B >4095) + { + LFO_B=LFO_B-8192; + } + + if(LFO_C>4095) + { + LFO_C=LFO_C-8192; + } + + if(LFO_D >4095) + { + LFO_D=LFO_D-8192; + } + LFO_A=LFO_A*312500/4096; + LFO_B=LFO_B*312500/4096; + LFO_C=LFO_C*312500/4096; + LFO_D=LFO_D*312500/4096; + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d/ %d/ %d", " End CFO(Hz) ", LFO_A,LFO_B,LFO_C,LFO_D); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xf20 ,bMaskDWord); //L SIG + + Tail=(u1Byte)((value32&0xfc0000)>>16); + Parity = (u1Byte)((value32&0x20000)>>16); + Length =(u2Byte)((value32&0x1ffe00)>>8); + rsv = (u1Byte)(value32&0x10); + MCSS=(u1Byte)(value32&0x0f); + + switch(MCSS) + { + case 0x0b: + idx=0; + break; + case 0x0f: + idx=1; + break; + case 0x0a: + idx=2; + break; + case 0x0e: + idx=3; + break; + case 0x09: + idx=4; + break; + case 0x08: + idx=5; + break; + case 0x0c: + idx=6; + break; + default: + idx=6; + break; + + } + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "L-SIG"); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Rate:%s", L_rate[idx]); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x/ %x /%x", " Rsv/Length/Parity",rsv,RX_BW,Length); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "HT-SIG1"); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xf2c ,bMaskDWord); //HT SIG + if(RX_HT == 1) + { + + HMCSS=(u1Byte)(value32&0x7F); + HRX_BW = (u1Byte)(value32&0x80); + HLength =(u2Byte)((value32>>8)&0xffff); + } + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x / %x/ %x", " MCS/BW/Length",HMCSS,HRX_BW,HLength); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "HT-SIG2"); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, 0xf30 ,bMaskDWord); //HT SIG + + if(RX_HT == 1) + { + smooth = (u1Byte)(value32&0x01); + htsound = (u1Byte)(value32&0x02); + rsv=(u1Byte)(value32&0x04); + agg =(u1Byte)(value32&0x08); + stbc =(u1Byte)(value32&0x30); + fec=(u1Byte)(value32&0x40); + sgi=(u1Byte)(value32&0x80); + htltf=(u1Byte)((value32&0x300)>>8); + htcrc8=(u2Byte)((value32&0x3fc00)>>8); + Tail=(u1Byte)((value32&0xfc0000)>>16); + + + } + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x / %x/ %x/ %x/ %x/ %x", " Smooth/NoSound/Rsv/Aggregate/STBC/LDPC",smooth,htsound,rsv,agg,stbc,fec); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x / %x/ %x/ %x", " SGI/E-HT-LTFs/CRC/Tail",sgi,htltf,htcrc8,Tail); + DCMD_Printf(BbDbgBuf); + + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "VHT-SIG-A1"); + DCMD_Printf(BbDbgBuf); + value32 = ODM_GetBBReg(pDM_Odm, 0xf2c ,bMaskDWord); //VHT SIG A1 + if(RX_HT == 2) + { + //value32 = ODM_GetBBReg(pDM_Odm, 0xf2c ,bMaskDWord); //VHT SIG A1 + vRX_BW=(u1Byte)(value32&0x03); + vrsv=(u1Byte)(value32&0x04); + vstbc =(u1Byte)(value32&0x08); + vgid = (u1Byte)((value32&0x3f0)>>4); + vNsts = (u1Byte)(((value32&0x1c00)>>8)+1); + vpaid = (u2Byte)(value32&0x3fe); + vtxops =(u1Byte)((value32&0x400000)>>20); + vrsv2 = (u1Byte)((value32&0x800000)>>20); + } + + //rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x", "F2C", value32); + //DCMD_Printf(BbDbgBuf); + + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x / %x/ %x/ %x/ %x/ %x /%x /%x", " BW/Rsv1/STBC/GID/Nsts/PAID/TXOPPS/Rsv2",vRX_BW,vrsv,vstbc,vgid,vNsts,vpaid,vtxops,vrsv2); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "VHT-SIG-A2"); + DCMD_Printf(BbDbgBuf); + value32 = ODM_GetBBReg(pDM_Odm, 0xf30 ,bMaskDWord); //VHT SIG + + + if(RX_HT == 2) + { + //value32 = ODM_GetBBReg(pDM_Odm, 0xf30 ,bMaskDWord); //VHT SIG + + //sgi=(u1Byte)(value32&0x01); + sgiext =(u1Byte)(value32&0x03); + //fec = (u1Byte)(value32&0x04); + fecext = (u1Byte)(value32&0x0C); + + vMCSS =(u1Byte)(value32&0xf0); + bf = (u1Byte)((value32&0x100)>>8); + vrsv =(u1Byte)((value32&0x200)>>8); + vhtcrc8=(u2Byte)((value32&0x3fc00)>>8); + vTail=(u1Byte)((value32&0xfc0000)>>16); + } + //rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x", "F30", value32); + //DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x / %x/ %x/ %x/ %x/ %x/ %x", " SGI/FEC/MCS/BF/Rsv/CRC/Tail",sgiext,fecext,vMCSS,bf,vrsv,vhtcrc8,vTail); + DCMD_Printf(BbDbgBuf); + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "VHT-SIG-B"); + DCMD_Printf(BbDbgBuf); + value32 = ODM_GetBBReg(pDM_Odm, 0xf34 ,bMaskDWord); //VHT SIG + { + vLength=(u2Byte)(value32&0x1fffff); + vbrsv = (u1Byte)((value32&0x600000)>>20); + vbTail =(u2Byte)((value32&0x1f800000)>>20); + vbcrc = (u1Byte)((value32&0x80000000)>>28); + + } + //rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x", "F34", value32); + //DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x / %x/ %x/ %x/", " Length/Rsv/Tail/CRC",vLength,vbrsv,vbTail,vbcrc); + DCMD_Printf(BbDbgBuf); + + +} + + +VOID phydm_BasicProfile( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + char* Cut = NULL; + char* ICType = NULL; + + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n%-35s", "% Basic Profile %"); + DCMD_Printf(BbDbgBuf); + + if(pDM_Odm->SupportICType == ODM_RTL8192C) + ICType = "RTL8192C"; + else if(pDM_Odm->SupportICType == ODM_RTL8192D) + ICType = "RTL8192D"; + else if(pDM_Odm->SupportICType == ODM_RTL8723A) + ICType = "RTL8723A"; + else if(pDM_Odm->SupportICType == ODM_RTL8188E) + ICType = "RTL8188E"; + else if(pDM_Odm->SupportICType == ODM_RTL8812) + ICType = "RTL8812A"; + else if(pDM_Odm->SupportICType == ODM_RTL8821) + ICType = "RTL8821A"; + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + ICType = "RTL8192E"; + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + ICType = "RTL8723B"; + else if(pDM_Odm->SupportICType == ODM_RTL8814A) + ICType = "RTL8814A"; + else if(pDM_Odm->SupportICType == ODM_RTL8881A) + ICType = "RTL8881A"; + else if(pDM_Odm->SupportICType == ODM_RTL8821B) + ICType = "RTL8821B"; + else if(pDM_Odm->SupportICType == ODM_RTL8822B) + ICType = "RTL8822B"; + else if(pDM_Odm->SupportICType == ODM_RTL8703B) + ICType = "RTL8703B"; + else if(pDM_Odm->SupportICType == ODM_RTL8195A) + ICType = "RTL8195A"; + else if(pDM_Odm->SupportICType == ODM_RTL8188F) + ICType = "RTL8188F"; + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s (MP Chip: %s)","IC Type", ICType, pDM_Odm->bIsMPChip?"Yes":"No"); + DCMD_Printf(BbDbgBuf); + + if(pDM_Odm->CutVersion==ODM_CUT_A) + Cut = "A"; + else if(pDM_Odm->CutVersion==ODM_CUT_B) + Cut = "B"; + else if(pDM_Odm->CutVersion==ODM_CUT_C) + Cut = "C"; + else if(pDM_Odm->CutVersion==ODM_CUT_D) + Cut = "D"; + else if(pDM_Odm->CutVersion==ODM_CUT_E) + Cut = "E"; + else if(pDM_Odm->CutVersion==ODM_CUT_F) + Cut = "F"; + else if(pDM_Odm->CutVersion==ODM_CUT_I) + Cut = "I"; + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Cut Version", Cut); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %d","PHY Parameter Version", ODM_GetHWImgVersion(pDM_Odm)); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %d (Subversion: %d)","FW Version", Adapter->MgntInfo.FirmwareVersion, Adapter->MgntInfo.FirmwareSubVersion); + DCMD_Printf(BbDbgBuf); + + //1 PHY DM Version List + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n%-35s","% PHYDM Version %"); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Adaptivity", ADAPTIVITY_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","DIG", DIG_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Dynamic BB PowerSaving", DYNAMIC_BBPWRSAV_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","CFO Tracking", CFO_TRACKING_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Antenna Diversity", ANTDIV_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Power Tracking", POWRTRACKING_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Dynamic TxPower", DYNAMIC_TXPWR_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","RA Info", RAINFO_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Antenna Detection", ANTDECT_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Auto Channel Selection", ACS_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","EDCA Turbo", EDCATURBO_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","Path Diversity", PATHDIV_VERSION); + DCMD_Printf(BbDbgBuf); + rsprintf(BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s: %s","RxHP", RXHP_VERSION); + DCMD_Printf(BbDbgBuf); + +} +#endif +VOID +phydm_BasicDbgMessage +( + IN PVOID pDM_VOID + ) +{ +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm , PHYDM_FALSEALMCNT); + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_BasicDbgMsg==>\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("bLinked = %d, RSSI_Min = %d, CurrentIGI = 0x%x \n", + pDM_Odm->bLinked, pDM_Odm->RSSI_Min, pDM_DigTable->CurIGValue) ); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("Cnt_Cck_fail = %d, Cnt_Ofdm_fail = %d, Total False Alarm = %d\n", + FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_all)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("RxRate = 0x%x, RSSI_A = %d, RSSI_B = %d\n", + pDM_Odm->RxRate, pDM_Odm->RSSI_A, pDM_Odm->RSSI_B)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("RSSI_C = %d, RSSI_D = %d\n", pDM_Odm->RSSI_C, pDM_Odm->RSSI_D)); +#endif +} + +#if( DM_ODM_SUPPORT_TYPE & ODM_CE) +struct _PHYDM_COMMAND { + char name[16]; + u1Byte id; +}; + +enum PHYDM_CMD_ID { + PHYDM_ANTDIV, +}; + +struct _PHYDM_COMMAND phy_dm_ary[] = { + {"antdiv", PHYDM_ANTDIV}, +}; + +s4Byte +PhyDM_Cmd( + IN PDM_ODM_T pDM_Odm, + IN char *input, + IN u4Byte in_len, + IN u1Byte flag, + OUT char *output, + IN u4Byte out_len + ) +{ + u4Byte used = 0; + + if (flag == 0) { + if (out_len > used) + used += snprintf(output+used, out_len-used, "GET, nothing to print\n"); + } else { + char *token; + u1Byte id = 0; + int var = 0; + + token = strsep(&input, ", "); + if (token) { + int n, i; + n = sizeof(phy_dm_ary)/sizeof(struct _PHYDM_COMMAND); + for (i = 0; i < n; i++) { + if (strcmp(phy_dm_ary[i].name, token) == 0) { + id = phy_dm_ary[i].id; + break; + } + } + if (i == n) { + if (out_len > used) + used += snprintf(output+used, out_len-used, "SET, command not found!\n"); + goto exit; + } + } + + switch (id) { + case PHYDM_ANTDIV: + token = strsep(&input, ", "); + sscanf(token, "%d", &var); + if (out_len > used) + used += snprintf(output+used, out_len-used, "SET, old antdiv_select=%d\n", pDM_Odm->antdiv_select); + pDM_Odm->antdiv_select = var; + if (out_len > used) + used += snprintf(output+used, out_len-used, "SET, new antdiv_select=%d\n", pDM_Odm->antdiv_select); + break; + + default: + if (out_len > used) + used += snprintf(output+used, out_len-used, "SET, unknown command!\n"); + break; + } + } + +exit: + return 0; +} +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_debug.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_debug.h new file mode 100755 index 000000000000..93574f2a0d90 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_debug.h @@ -0,0 +1,202 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __ODM_DBG_H__ +#define __ODM_DBG_H__ + + +//----------------------------------------------------------------------------- +// Define the debug levels +// +// 1. DBG_TRACE and DBG_LOUD are used for normal cases. +// So that, they can help SW engineer to develope or trace states changed +// and also help HW enginner to trace every operation to and from HW, +// e.g IO, Tx, Rx. +// +// 2. DBG_WARNNING and DBG_SERIOUS are used for unusual or error cases, +// which help us to debug SW or HW. +// +//----------------------------------------------------------------------------- +// +// Never used in a call to ODM_RT_TRACE()! +// +#define ODM_DBG_OFF 1 + +// +// Fatal bug. +// For example, Tx/Rx/IO locked up, OS hangs, memory access violation, +// resource allocation failed, unexpected HW behavior, HW BUG and so on. +// +#define ODM_DBG_SERIOUS 2 + +// +// Abnormal, rare, or unexpeted cases. +// For example, IRP/Packet/OID canceled, device suprisely unremoved and so on. +// +#define ODM_DBG_WARNING 3 + +// +// Normal case with useful information about current SW or HW state. +// For example, Tx/Rx descriptor to fill, Tx/Rx descriptor completed status, +// SW protocol state change, dynamic mechanism state change and so on. +// +#define ODM_DBG_LOUD 4 + +// +// Normal case with detail execution flow or information. +// +#define ODM_DBG_TRACE 5 + +//----------------------------------------------------------------------------- +// Define the tracing components +// +//----------------------------------------------------------------------------- +//BB Functions +#define ODM_COMP_DIG BIT0 +#define ODM_COMP_RA_MASK BIT1 +#define ODM_COMP_DYNAMIC_TXPWR BIT2 +#define ODM_COMP_FA_CNT BIT3 +#define ODM_COMP_RSSI_MONITOR BIT4 +#define ODM_COMP_CCK_PD BIT5 +#define ODM_COMP_ANT_DIV BIT6 +#define ODM_COMP_PWR_SAVE BIT7 +#define ODM_COMP_PWR_TRAIN BIT8 +#define ODM_COMP_RATE_ADAPTIVE BIT9 +#define ODM_COMP_PATH_DIV BIT10 +#define ODM_COMP_PSD BIT11 +#define ODM_COMP_DYNAMIC_PRICCA BIT12 +#define ODM_COMP_RXHP BIT13 +#define ODM_COMP_MP BIT14 +#define ODM_COMP_CFO_TRACKING BIT15 +#define ODM_COMP_ACS BIT16 +#define PHYDM_COMP_ADAPTIVITY BIT17 +//MAC Functions +#define ODM_COMP_EDCA_TURBO BIT20 +#define ODM_COMP_EARLY_MODE BIT21 +//RF Functions +#define ODM_COMP_TX_PWR_TRACK BIT24 +#define ODM_COMP_RX_GAIN_TRACK BIT25 +#define ODM_COMP_CALIBRATION BIT26 +//Common Functions +#define ODM_COMP_COMMON BIT30 +#define ODM_COMP_INIT BIT31 + +/*------------------------Export Marco Definition---------------------------*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #define RT_PRINTK DbgPrint +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #define DbgPrint printk + #define RT_PRINTK(fmt, args...) DbgPrint( "%s(): " fmt, __FUNCTION__, ## args); + #define RT_DISP(dbgtype, dbgflag, printstr) +#else + #define DbgPrint panic_printk + #define RT_PRINTK(fmt, args...) DbgPrint( "%s(): " fmt, __FUNCTION__, ## args); +#endif + +#ifndef ASSERT + #define ASSERT(expr) +#endif + +#if DBG +#define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) \ + if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel || level == ODM_DBG_SERIOUS)) \ + { \ + if(pDM_Odm->SupportICType == ODM_RTL8192C) \ + DbgPrint("[ODM-92C] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8192D) \ + DbgPrint("[ODM-92D] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8723A) \ + DbgPrint("[ODM-8723A] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8188E) \ + DbgPrint("[ODM-8188E] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8192E) \ + DbgPrint("[ODM-8192E] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8812) \ + DbgPrint("[ODM-8812] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8821) \ + DbgPrint("[ODM-8821] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8814A) \ + DbgPrint("[ODM-8814] "); \ + RT_PRINTK fmt; \ + } + +#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) \ + if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel)) \ + { \ + RT_PRINTK fmt; \ + } + +#define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ + if(!(expr)) { \ + DbgPrint( "Assertion failed! %s at ......\n", #expr); \ + DbgPrint( " ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__); \ + RT_PRINTK fmt; \ + ASSERT(FALSE); \ + } +#define ODM_dbg_enter() { DbgPrint("==> %s\n", __FUNCTION__); } +#define ODM_dbg_exit() { DbgPrint("<== %s\n", __FUNCTION__); } +#define ODM_dbg_trace(str) { DbgPrint("%s:%s\n", __FUNCTION__, str); } + +#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ + if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel)) \ + { \ + int __i; \ + pu1Byte __ptr = (pu1Byte)ptr; \ + DbgPrint("[ODM] "); \ + DbgPrint(title_str); \ + DbgPrint(" "); \ + for( __i=0; __i<6; __i++ ) \ + DbgPrint("%02X%s", __ptr[__i], (__i==5)?"":"-"); \ + DbgPrint("\n"); \ + } +#else +#define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) +#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) +#define ODM_RT_ASSERT(pDM_Odm, expr, fmt) +#define ODM_dbg_enter() +#define ODM_dbg_exit() +#define ODM_dbg_trace(str) +#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) +#endif + + +VOID +PHYDM_InitDebugSetting(IN PDM_ODM_T pDM_Odm); + +#define BB_TMP_BUF_SIZE 100 +VOID phydm_BB_Debug_Info(IN PDM_ODM_T pDM_Odm); +VOID phydm_BasicProfile(IN PVOID pDM_VOID); +VOID phydm_BasicDbgMessage( IN PVOID pDM_VOID); + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +s4Byte +PhyDM_Cmd( + IN PDM_ODM_T pDM_Odm, + IN char *input, + IN u4Byte in_len, + IN u1Byte flag, + OUT char *output, + IN u4Byte out_len +); +#endif + +#endif // __ODM_DBG_H__ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_interface.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_interface.c new file mode 100755 index 000000000000..16caf370b73c --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_interface.c @@ -0,0 +1,835 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ + +#include "Mp_Precomp.h" +#include "phydm_precomp.h" + +// +// ODM IO Relative API. +// + +u1Byte +ODM_Read1Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + return RTL_R8(RegAddr); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + return rtw_read8(Adapter,RegAddr); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + return PlatformEFIORead1Byte(Adapter, RegAddr); +#endif + +} + + +u2Byte +ODM_Read2Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + return RTL_R16(RegAddr); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + return rtw_read16(Adapter,RegAddr); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + return PlatformEFIORead2Byte(Adapter, RegAddr); +#endif + +} + + +u4Byte +ODM_Read4Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + return RTL_R32(RegAddr); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + return rtw_read32(Adapter,RegAddr); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + return PlatformEFIORead4Byte(Adapter, RegAddr); +#endif + +} + + +VOID +ODM_Write1Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u1Byte Data + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + RTL_W8(RegAddr, Data); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + rtw_write8(Adapter,RegAddr, Data); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformEFIOWrite1Byte(Adapter, RegAddr, Data); +#endif + +} + + +VOID +ODM_Write2Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u2Byte Data + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + RTL_W16(RegAddr, Data); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + rtw_write16(Adapter,RegAddr, Data); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformEFIOWrite2Byte(Adapter, RegAddr, Data); +#endif + +} + + +VOID +ODM_Write4Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte Data + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv = pDM_Odm->priv; + RTL_W32(RegAddr, Data); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + rtw_write32(Adapter,RegAddr, Data); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformEFIOWrite4Byte(Adapter, RegAddr, Data); +#endif + +} + + +VOID +ODM_SetMACReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + PHY_SetBBReg(pDM_Odm->priv, RegAddr, BitMask, Data); +#elif(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; + PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); +#endif +} + + +u4Byte +ODM_GetMACReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + return PHY_QueryBBReg(pDM_Odm->priv, RegAddr, BitMask); +#elif(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + return PHY_QueryMacReg(pDM_Odm->Adapter, RegAddr, BitMask); +#endif +} + + +VOID +ODM_SetBBReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + PHY_SetBBReg(pDM_Odm->priv, RegAddr, BitMask, Data); +#elif(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; + PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); +#endif +} + + +u4Byte +ODM_GetBBReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + return PHY_QueryBBReg(pDM_Odm->priv, RegAddr, BitMask); +#elif(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; + return PHY_QueryBBReg(Adapter, RegAddr, BitMask); +#endif +} + + +VOID +ODM_SetRFReg( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_RADIO_PATH_E eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + PHY_SetRFReg(pDM_Odm->priv, eRFPath, RegAddr, BitMask, Data); +#elif(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; + PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data); +#endif +} + + +u4Byte +ODM_GetRFReg( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_RADIO_PATH_E eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + return PHY_QueryRFReg(pDM_Odm->priv, eRFPath, RegAddr, BitMask, 1); +#elif(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + PADAPTER Adapter = pDM_Odm->Adapter; + return PHY_QueryRFReg(Adapter, eRFPath, RegAddr, BitMask); +#endif +} + + + + +// +// ODM Memory relative API. +// +VOID +ODM_AllocateMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID *pPtr, + IN u4Byte length + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + *pPtr = kmalloc(length, GFP_ATOMIC); +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE ) + *pPtr = rtw_zvmalloc(length); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformAllocateMemory(Adapter, pPtr, length); +#endif +} + +// length could be ignored, used to detect memory leakage. +VOID +ODM_FreeMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID pPtr, + IN u4Byte length + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + kfree(pPtr); +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE ) + rtw_vmfree(pPtr, length); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + //PADAPTER Adapter = pDM_Odm->Adapter; + PlatformFreeMemory(pPtr, length); +#endif +} + +VOID +ODM_MoveMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID pDest, + IN PVOID pSrc, + IN u4Byte Length + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + memcpy(pDest, pSrc, Length); +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE ) + _rtw_memcpy(pDest, pSrc, Length); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformMoveMemory(pDest, pSrc, Length); +#endif +} + +void ODM_Memory_Set + (IN PDM_ODM_T pDM_Odm, + IN PVOID pbuf, + IN s1Byte value, + IN u4Byte length) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE ) + _rtw_memset(pbuf,value, length); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformFillMemory(pbuf,length,value); +#endif +} +s4Byte ODM_CompareMemory( + IN PDM_ODM_T pDM_Odm, + IN PVOID pBuf1, + IN PVOID pBuf2, + IN u4Byte length + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + return memcmp(pBuf1,pBuf2,length); +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE ) + return _rtw_memcmp(pBuf1,pBuf2,length); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + return PlatformCompareMemory(pBuf1,pBuf2,length); +#endif +} + + + +// +// ODM MISC relative API. +// +VOID +ODM_AcquireSpinLock( + IN PDM_ODM_T pDM_Odm, + IN RT_SPINLOCK_TYPE type + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + rtw_odm_acquirespinlock(Adapter, type); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformAcquireSpinLock(Adapter, type); +#endif +} +VOID +ODM_ReleaseSpinLock( + IN PDM_ODM_T pDM_Odm, + IN RT_SPINLOCK_TYPE type + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE ) + PADAPTER Adapter = pDM_Odm->Adapter; + rtw_odm_releasespinlock(Adapter, type); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformReleaseSpinLock(Adapter, type); +#endif +} + +// +// Work item relative API. FOr MP driver only~! +// +VOID +ODM_InitializeWorkItem( + IN PDM_ODM_T pDM_Odm, + IN PRT_WORK_ITEM pRtWorkItem, + IN RT_WORKITEM_CALL_BACK RtWorkItemCallback, + IN PVOID pContext, + IN const char* szID + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformInitializeWorkItem(Adapter, pRtWorkItem, RtWorkItemCallback, pContext, szID); +#endif +} + + +VOID +ODM_StartWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformStartWorkItem(pRtWorkItem); +#endif +} + + +VOID +ODM_StopWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformStopWorkItem(pRtWorkItem); +#endif +} + + +VOID +ODM_FreeWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformFreeWorkItem(pRtWorkItem); +#endif +} + + +VOID +ODM_ScheduleWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformScheduleWorkItem(pRtWorkItem); +#endif +} + + +VOID +ODM_IsWorkItemScheduled( + IN PRT_WORK_ITEM pRtWorkItem + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformIsWorkItemScheduled(pRtWorkItem); +#endif +} + + + +// +// ODM Timer relative API. +// +VOID +ODM_StallExecution( + IN u4Byte usDelay + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + rtw_udelay_os(usDelay); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformStallExecution(usDelay); +#endif +} + +VOID +ODM_delay_ms(IN u4Byte ms) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + delay_ms(ms); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + rtw_mdelay_os(ms); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + delay_ms(ms); +#endif +} + +VOID +ODM_delay_us(IN u4Byte us) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + delay_us(us); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + rtw_udelay_os(us); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PlatformStallExecution(us); +#endif +} + +VOID +ODM_sleep_ms(IN u4Byte ms) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + rtw_msleep_os(ms); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) +#endif +} + +VOID +ODM_sleep_us(IN u4Byte us) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + rtw_usleep_os(us); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) +#endif +} + +VOID +ODM_SetTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer, + IN u4Byte msDelay + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + mod_timer(pTimer, jiffies + RTL_MILISECONDS_TO_JIFFIES(msDelay)); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + _set_timer(pTimer,msDelay ); //ms +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformSetTimer(Adapter, pTimer, msDelay); +#endif + +} + +VOID +ODM_InitializeTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer, + IN RT_TIMER_CALL_BACK CallBackFunc, + IN PVOID pContext, + IN const char* szID + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + init_timer(pTimer); + pTimer->function = CallBackFunc; + pTimer->data = (unsigned long)pDM_Odm; + mod_timer(pTimer, jiffies+RTL_MILISECONDS_TO_JIFFIES(10)); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + PADAPTER Adapter = pDM_Odm->Adapter; + _init_timer(pTimer,Adapter->pnetdev,CallBackFunc,pDM_Odm); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformInitializeTimer(Adapter, pTimer, CallBackFunc,pContext,szID); +#endif +} + + +VOID +ODM_CancelTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + del_timer_sync(pTimer); +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + _cancel_timer_ex(pTimer); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PlatformCancelTimer(Adapter, pTimer); +#endif +} + + +VOID +ODM_ReleaseTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + + PADAPTER Adapter = pDM_Odm->Adapter; + + // <20120301, Kordan> If the initilization fails, InitializeAdapterXxx will return regardless of InitHalDm. + // Hence, uninitialized timers cause BSOD when the driver releases resources since the init fail. + if (pTimer == 0) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_SERIOUS, ("=====>ODM_ReleaseTimer(), The timer is NULL! Please check it!\n")); + return; + } + + PlatformReleaseTimer(Adapter, pTimer); +#endif +} + + +// +// ODM FW relative API. +// +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +ODM_FillH2CCmd( + IN PDM_ODM_T pDM_Odm, + IN u1Byte ElementID, + IN u4Byte CmdLen, + IN pu1Byte pCmdBuffer +) +{ + PADAPTER Adapter = pDM_Odm->Adapter; + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + switch(ElementID) + { + case ODM_H2C_RSSI_REPORT: + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + FillH2CCmd(Adapter, H2C_RSSI_REPORT, CmdLen, pCmdBuffer); +#else + #if((RTL8812A_SUPPORT==1) ||(RTL8821A_SUPPORT==1)) + FillH2CCmd_8812(Adapter, H2C_8812_RSSI_REPORT, CmdLen, pCmdBuffer); + #endif +#endif + break; + case ODM_H2C_IQ_CALIBRATION: +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + FillH2CCmd(Adapter, H2C_IQ_CALIBRATION, CmdLen, pCmdBuffer); +#else + #if((RTL8812A_SUPPORT==1) ||(RTL8821A_SUPPORT==1)) + FillH2CCmd_8812(Adapter, H2C_8812_IQ_CALIBRATION, CmdLen, pCmdBuffer); + #endif +#endif + break; + default: + break; + } + + } + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + switch(ElementID) + { + case ODM_H2C_RSSI_REPORT: +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + FillH2CCmd(Adapter, H2C_RSSI_REPORT, CmdLen, pCmdBuffer); +#else + #if(RTL8192E_SUPPORT==1) + FillH2CCmd_8192E(Adapter, H2C_8192E_RSSI_REPORT, CmdLen, pCmdBuffer); + #endif +#endif + break; + default: + break; + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + switch(ElementID) + { + case ODM_H2C_RSSI_REPORT: +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + FillH2CCmd(Adapter, H2C_RSSI_REPORT, CmdLen, pCmdBuffer); +#else + #if(RTL8723B_SUPPORT==1) + FillH2CCmd8723B(Adapter, H2C_8723B_RSSI_SETTING, CmdLen, pCmdBuffer); + #endif +#endif + break; + case ODM_H2C_WIFI_CALIBRATION: +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + FillH2CCmd(Adapter, H2C_WIFI_CALIBRATION, CmdLen, pCmdBuffer); +#else + #if(RTL8723B_SUPPORT==1) + FillH2CCmd8723B(Adapter, H2C_8723B_BT_WLAN_CALIBRATION, CmdLen, pCmdBuffer); + #endif +#endif + break; + default: + break; + } + + } + else if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + switch(ElementID) + { + case ODM_H2C_RSSI_REPORT: + //if((pDM_Odm->CutVersion == ODM_CUT_I) && (!pDM_Odm->RaSupport88E)){ + if(!pDM_Odm->RaSupport88E){ +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + FillH2CCmd88E(Adapter, H2C_88E_RSSI_REPORT, CmdLen, pCmdBuffer); +#else + #if(RTL8188E_SUPPORT==1) + FillH2CCmd_88E(Adapter, H2C_RSSI_REPORT, CmdLen, pCmdBuffer); + #endif +#endif + } + break; + default: + break; + } + } +#if(DM_ODM_SUPPORT_TYPE & ODM_CE) + else if(pDM_Odm->SupportICType == ODM_RTL8723A) + { + switch(ElementID) + { + case ODM_H2C_RSSI_REPORT: + #if(RTL8723A_SUPPORT==1) + FillH2CCmd(Adapter, RSSI_SETTING_EID, CmdLen, pCmdBuffer); + #endif + break; + default: + break; + } + } + else if(pDM_Odm->SupportICType == ODM_RTL8192D) + { + switch(ElementID) + { + case ODM_H2C_RSSI_REPORT: + #if(RTL8192D_SUPPORT==1) + FillH2CCmd92D(Adapter, H2C_RSSI_REPORT, CmdLen, pCmdBuffer); + #endif + break; + default: + break; + } + } +#endif + else + { + switch(ElementID) + { + case ODM_H2C_RSSI_REPORT: +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + FillH2CCmd92C(Adapter, H2C_RSSI_REPORT, CmdLen, pCmdBuffer); +#else + #if(RTL8192C_SUPPORT==1) + rtl8192c_FillH2CCmd(Adapter, RSSI_SETTING_EID, CmdLen, pCmdBuffer); + #endif +#endif + break; + default: + break; + } + } +} +#else +u4Byte +ODM_FillH2CCmd( + IN pu1Byte pH2CBuffer, + IN u4Byte H2CBufferLen, + IN u4Byte CmdNum, + IN pu4Byte pElementID, + IN pu4Byte pCmdLen, + IN pu1Byte* pCmbBuffer, + IN pu1Byte CmdStartSeq + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + //FillH2CCmd(pH2CBuffer, H2CBufferLen, CmdNum, pElementID, pCmdLen, pCmbBuffer, CmdStartSeq); + return FALSE; +#endif + + return TRUE; +} +#endif + + +u8Byte +ODM_GetCurrentTime( + IN PDM_ODM_T pDM_Odm + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + return 0; +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + return (u8Byte)rtw_get_current_time(); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + return PlatformGetCurrentTime(); +#endif +} + +u8Byte +ODM_GetProgressingTime( + IN PDM_ODM_T pDM_Odm, + IN u8Byte Start_Time + ) +{ +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + return 0; +#elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + return rtw_get_passing_time_ms((u4Byte)Start_Time); +#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) + return ((PlatformGetCurrentTime() - Start_Time)>>10); +#endif +} + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_interface.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_interface.h new file mode 100755 index 000000000000..6a6d50ce6953 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_interface.h @@ -0,0 +1,414 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __ODM_INTERFACE_H__ +#define __ODM_INTERFACE_H__ + + + +// +// =========== Constant/Structure/Enum/... Define +// + + + +// +// =========== Macro Define +// + +#define _reg_all(_name) ODM_##_name +#define _reg_ic(_name, _ic) ODM_##_name##_ic +#define _bit_all(_name) BIT_##_name +#define _bit_ic(_name, _ic) BIT_##_name##_ic + +// _cat: implemented by Token-Pasting Operator. +#if 0 +#define _cat(_name, _ic_type, _func) \ + ( \ + _func##_all(_name) \ + ) +#endif + +/*=================================== + +#define ODM_REG_DIG_11N 0xC50 +#define ODM_REG_DIG_11AC 0xDDD + +ODM_REG(DIG,_pDM_Odm) +=====================================*/ + +#define _reg_11N(_name) ODM_REG_##_name##_11N +#define _reg_11AC(_name) ODM_REG_##_name##_11AC +#define _bit_11N(_name) ODM_BIT_##_name##_11N +#define _bit_11AC(_name) ODM_BIT_##_name##_11AC + +#ifdef __ECOS +#define _rtk_cat(_name, _ic_type, _func) \ + ( \ + ((_ic_type) & ODM_IC_11N_SERIES)? _func##_11N(_name): \ + _func##_11AC(_name) \ + ) +#else + +#define _cat(_name, _ic_type, _func) \ + ( \ + ((_ic_type) & ODM_IC_11N_SERIES)? _func##_11N(_name): \ + _func##_11AC(_name) \ + ) +#endif +/* +// only sample code +//#define _cat(_name, _ic_type, _func) \ +// ( \ +// ((_ic_type) & ODM_RTL8192C)? _func##_ic(_name, _8192C): \ +// ((_ic_type) & ODM_RTL8192D)? _func##_ic(_name, _8192D): \ +// ((_ic_type) & ODM_RTL8192S)? _func##_ic(_name, _8192S): \ +// ((_ic_type) & ODM_RTL8723A)? _func##_ic(_name, _8723A): \ +// ((_ic_type) & ODM_RTL8188E)? _func##_ic(_name, _8188E): \ +// _func##_ic(_name, _8195) \ +// ) +*/ + +// _name: name of register or bit. +// Example: "ODM_REG(R_A_AGC_CORE1, pDM_Odm)" +// gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", depends on SupportICType. +#ifdef __ECOS +#define ODM_REG(_name, _pDM_Odm) _rtk_cat(_name, _pDM_Odm->SupportICType, _reg) +#define ODM_BIT(_name, _pDM_Odm) _rtk_cat(_name, _pDM_Odm->SupportICType, _bit) +#else +#define ODM_REG(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _reg) +#define ODM_BIT(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _bit) +#endif +typedef enum _ODM_H2C_CMD +{ + ODM_H2C_RSSI_REPORT = 0, + ODM_H2C_PSD_RESULT=1, + ODM_H2C_PathDiv = 2, + ODM_H2C_WIFI_CALIBRATION = 3, + ODM_H2C_IQ_CALIBRATION = 4, + ODM_MAX_H2CCMD +}ODM_H2C_CMD; + + +// +// 2012/02/17 MH For non-MP compile pass only. Linux does not support workitem. +// Suggest HW team to use thread instead of workitem. Windows also support the feature. +// +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +typedef void *PRT_WORK_ITEM ; +typedef void RT_WORKITEM_HANDLE,*PRT_WORKITEM_HANDLE; +typedef VOID (*RT_WORKITEM_CALL_BACK)(PVOID pContext); + +#if 0 +typedef struct tasklet_struct RT_WORKITEM_HANDLE, *PRT_WORKITEM_HANDLE; + +typedef struct _RT_WORK_ITEM +{ + + RT_WORKITEM_HANDLE Handle; // Platform-dependent handle for this workitem, e.g. Ndis Workitem object. + PVOID Adapter; // Pointer to Adapter object. + PVOID pContext; // Parameter to passed to CallBackFunc(). + RT_WORKITEM_CALL_BACK CallbackFunc; // Callback function of the workitem. + u1Byte RefCount; // 0: driver is going to unload, 1: No such workitem scheduled, 2: one workitem is schedueled. + PVOID pPlatformExt; // Pointer to platform-dependent extension. + BOOLEAN bFree; + char szID[36]; // An identity string of this workitem. +}RT_WORK_ITEM, *PRT_WORK_ITEM; + +#endif + + +#endif + +// +// =========== Extern Variable ??? It should be forbidden. +// + + +// +// =========== EXtern Function Prototype +// + + +u1Byte +ODM_Read1Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ); + +u2Byte +ODM_Read2Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ); + +u4Byte +ODM_Read4Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ); + +VOID +ODM_Write1Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u1Byte Data + ); + +VOID +ODM_Write2Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u2Byte Data + ); + +VOID +ODM_Write4Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte Data + ); + +VOID +ODM_SetMACReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); + +u4Byte +ODM_GetMACReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); + +VOID +ODM_SetBBReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); + +u4Byte +ODM_GetBBReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); + +VOID +ODM_SetRFReg( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_RADIO_PATH_E eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); + +u4Byte +ODM_GetRFReg( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_RADIO_PATH_E eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); + + +// +// Memory Relative Function. +// +VOID +ODM_AllocateMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID *pPtr, + IN u4Byte length + ); +VOID +ODM_FreeMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID pPtr, + IN u4Byte length + ); + +VOID +ODM_MoveMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID pDest, + IN PVOID pSrc, + IN u4Byte Length + ); + +s4Byte ODM_CompareMemory( + IN PDM_ODM_T pDM_Odm, + IN PVOID pBuf1, + IN PVOID pBuf2, + IN u4Byte length + ); + +void ODM_Memory_Set + (IN PDM_ODM_T pDM_Odm, + IN PVOID pbuf, + IN s1Byte value, + IN u4Byte length); + +// +// ODM MISC-spin lock relative API. +// +VOID +ODM_AcquireSpinLock( + IN PDM_ODM_T pDM_Odm, + IN RT_SPINLOCK_TYPE type + ); + +VOID +ODM_ReleaseSpinLock( + IN PDM_ODM_T pDM_Odm, + IN RT_SPINLOCK_TYPE type + ); + + +// +// ODM MISC-workitem relative API. +// +VOID +ODM_InitializeWorkItem( + IN PDM_ODM_T pDM_Odm, + IN PRT_WORK_ITEM pRtWorkItem, + IN RT_WORKITEM_CALL_BACK RtWorkItemCallback, + IN PVOID pContext, + IN const char* szID + ); + +VOID +ODM_StartWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_StopWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_FreeWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_ScheduleWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_IsWorkItemScheduled( + IN PRT_WORK_ITEM pRtWorkItem + ); + +// +// ODM Timer relative API. +// +VOID +ODM_StallExecution( + IN u4Byte usDelay + ); + +VOID +ODM_delay_ms(IN u4Byte ms); + + + +VOID +ODM_delay_us(IN u4Byte us); + +VOID +ODM_sleep_ms(IN u4Byte ms); + +VOID +ODM_sleep_us(IN u4Byte us); + +VOID +ODM_SetTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer, + IN u4Byte msDelay + ); + +VOID +ODM_InitializeTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer, + IN RT_TIMER_CALL_BACK CallBackFunc, + IN PVOID pContext, + IN const char* szID + ); + +VOID +ODM_CancelTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer + ); + +VOID +ODM_ReleaseTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer + ); + + +// +// ODM FW relative API. +// +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +ODM_FillH2CCmd( + IN PDM_ODM_T pDM_Odm, + IN u1Byte ElementID, + IN u4Byte CmdLen, + IN pu1Byte pCmdBuffer +); +#else +u4Byte +ODM_FillH2CCmd( + IN pu1Byte pH2CBuffer, + IN u4Byte H2CBufferLen, + IN u4Byte CmdNum, + IN pu4Byte pElementID, + IN pu4Byte pCmdLen, + IN pu1Byte* pCmbBuffer, + IN pu1Byte CmdStartSeq + ); +#endif + +u8Byte +ODM_GetCurrentTime( + IN PDM_ODM_T pDM_Odm + ); +u8Byte +ODM_GetProgressingTime( + IN PDM_ODM_T pDM_Odm, + IN u8Byte Start_Time + ); + +#endif // __ODM_INTERFACE_H__ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_precomp.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_precomp.h new file mode 100755 index 000000000000..5651d7eaa190 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_precomp.h @@ -0,0 +1,296 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __ODM_PRECOMP_H__ +#define __ODM_PRECOMP_H__ + +#include "phydm_types.h" + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#include "Precomp.h" // We need to include mp_precomp.h due to batch file setting. + +#else + +#define TEST_FALG___ 1 + +#endif + +//2 Config Flags and Structs - defined by each ODM Type + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + #include "../8192cd_cfg.h" + #include "../odm_inc.h" + + #include "../8192cd.h" + #include "../8192cd_util.h" + #ifdef _BIG_ENDIAN_ + #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG + #else + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #endif + + #ifdef AP_BUILD_WORKAROUND + #include "../8192cd_headers.h" + #include "../8192cd_debug.h" + #endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + // Flags + #include "../8192cd_cfg.h" // OUTSRC needs ADSL config flags. + #include "../odm_inc.h" // OUTSRC needs some extra flags. + // Data Structure + #include "../common_types.h" // OUTSRC and rtl8192cd both needs basic type such as UINT8 and BIT0. + #include "../8192cd.h" // OUTSRC needs basic ADSL struct definition. + #include "../8192cd_util.h" // OUTSRC needs basic I/O function. + #ifdef _BIG_ENDIAN_ + #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG + #else + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #endif + + #ifdef ADSL_AP_BUILD_WORKAROUND + // NESTED_INC: Functions defined outside should not be included!! Marked by Annie, 2011-10-14. + #include "../8192cd_headers.h" + #include "../8192cd_debug.h" + #endif + +#elif (DM_ODM_SUPPORT_TYPE ==ODM_CE) + //#include + //#include + //#include + //#include + //#include + //#include +#define BEAMFORMING_SUPPORT 0 +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "Mp_Precomp.h" + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE +#endif + + +//2 Hardware Parameter Files + + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#if (RTL8192C_SUPPORT==1) + #include "rtl8192c/Hal8192CEFWImg_AP.h" + #include "rtl8192c/Hal8192CEPHYImg_AP.h" + #include "rtl8192c/Hal8192CEMACImg_AP.h" +#endif +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + #include "rtl8192c/Hal8192CEFWImg_ADSL.h" + #include "rtl8192c/Hal8192CEPHYImg_ADSL.h" + #include "rtl8192c/Hal8192CEMACImg_ADSL.h" + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #if(RTL8192CE_SUPPORT ==1) + #include "rtl8192c/Hal8192CEFWImg_CE.h" + #include "rtl8192c/Hal8192CEPHYImg_CE.h" + #include "rtl8192c/Hal8192CEMACImg_CE.h" + #endif + + #if(RTL8192CU_SUPPORT ==1) + #include "rtl8192c/Hal8192CUFWImg_CE.h" + #include "rtl8192c/Hal8192CUPHYImg_CE.h" + #include "rtl8192c/Hal8192CUMACImg_CE.h" + #endif + + #if(RTL8192DE_SUPPORT ==1) + #include "rtl8192d/Hal8192DEFWImg_CE.h" + #include "rtl8192d/Hal8192DEPHYImg_CE.h" + #include "rtl8192d/Hal8192DEMACImg_CE.h" + #endif + + #if(RTL8192DU_SUPPORT ==1) + #include "rtl8192d/Hal8192DUFWImg_CE.h" + #include "rtl8192d/Hal8192DUPHYImg_CE.h" + #include "rtl8192d/Hal8192DUMACImg_CE.h" + #endif + + #if(RTL8723AS_SUPPORT==1) + #include "rtl8723a/Hal8723SHWImg_CE.h" + #endif + + #if(RTL8723AU_SUPPORT==1) + #include "rtl8723a/Hal8723UHWImg_CE.h" + #endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#endif + + +//2 OutSrc Header Files +#include "phydm.h" +#include "phydm_HWConfig.h" +#include "phydm_debug.h" +#include "phydm_RegDefine11AC.h" +#include "phydm_RegDefine11N.h" +#include "phydm_AntDiv.h" +#include "phydm_interface.h" +#include "phydm_reg.h" + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#if (RTL8192C_SUPPORT==1) + #include "rtl8192c/HalDMOutSrc8192C_AP.h" +#endif +#if (RTL8188E_SUPPORT==1) + #include "rtl8188e/Hal8188ERateAdaptive.h"//for RA,Power training +#endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + #include "rtl8192c/HalDMOutSrc8192C_ADSL.h" + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + //#include "hal_com.h" + #include "HalPhyRf.h" + #if (RTL8192C_SUPPORT==1) + #ifdef CONFIG_INTEL_PROXIM + #include "../proxim/intel_proxim.h" + #endif + #include "rtl8192c/HalDMOutSrc8192C_CE.h" + #include + #endif + + #if (RTL8192D_SUPPORT==1) + #include "rtl8192d/HalDMOutSrc8192D_CE.h" + #include "rtl8192d_hal.h" + #endif + + #if (RTL8723A_SUPPORT==1) + #include "rtl8192c/HalDMOutSrc8192C_CE.h" //for IQK,LCK,Power-tracking + #include "rtl8723a_hal.h" + #endif + + #if (RTL8188E_SUPPORT==1) + #include "rtl8188e/HalPhyRf_8188e.h"//for IQK,LCK,Power-tracking + #include "rtl8188e/Hal8188ERateAdaptive.h"//for RA,Power training + #include "rtl8188e_hal.h" + #endif + + #if (RTL8192E_SUPPORT==1) + #include "rtl8192e/HalPhyRf_8192e.h"//for IQK,LCK,Power-tracking + #include "rtl8192e_hal.h" + #endif + + #if (RTL8812A_SUPPORT==1) + #include "rtl8812a/HalPhyRf_8812A.h"//for IQK,LCK,Power-tracking + #include "rtl8812a_hal.h" + #endif + + #if (RTL8821A_SUPPORT==1) + #include "rtl8821a/HalPhyRf_8821A.h"//for IQK,LCK,Power-tracking + #include "rtl8812a/HalPhyRf_8812A.h"//for IQK,LCK,Power-tracking + #include "rtl8812a_hal.h" + #include "rtl8821a/PhyDM_IQK_8821A.h" + #endif + + #if (RTL8723B_SUPPORT==1) + #include "rtl8723b/HalPhyRf_8723B.h"//for IQK,LCK,Power-tracking + #include "rtl8723b_hal.h" + #endif +#endif + + +#if (RTL8192C_SUPPORT==1) +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#include "rtl8192c/Hal8192CHWImg_MAC.h" +#include "rtl8192c/Hal8192CHWImg_RF.h" +#include "rtl8192c/Hal8192CHWImg_BB.h" +#include "rtl8192c/Hal8192CHWImg_FW.h" +#endif +#include "rtl8192c/phydm_RTL8192C.h" +#endif +#if (RTL8192D_SUPPORT==1) +#include "rtl8192d/phydm_RTL8192D.h" +#endif + +#if (RTL8723A_SUPPORT==1) +#include "rtl8723a/HalHWImg8723A_MAC.h" +#include "rtl8723a/HalHWImg8723A_RF.h" +#include "rtl8723a/HalHWImg8723A_BB.h" +#include "rtl8723a/HalHWImg8723A_FW.h" +#include "rtl8723a/phydm_RegConfig8723A.h" +#endif + +#if (RTL8188E_SUPPORT==1) +#include "rtl8188e/HalHWImg8188E_MAC.h" +#include "rtl8188e/HalHWImg8188E_RF.h" +#include "rtl8188e/HalHWImg8188E_BB.h" +#include "rtl8188e/HalHWImg8188E_FW.h" +#include "rtl8188e/Hal8188EReg.h" + +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) +#include "rtl8188e/HalPhyRf_8188e.h" +#endif + +#if (TESTCHIP_SUPPORT == 1) +#include "rtl8188e/HalHWImg8188E_TestChip_MAC.h" +#include "rtl8188e/HalHWImg8188E_TestChip_RF.h" +#include "rtl8188e/HalHWImg8188E_TestChip_BB.h" +#endif + + +#include "rtl8188e/phydm_RegConfig8188E.h" +#include "rtl8188e/phydm_RTL8188E.h" +#endif + +#if (RTL8192E_SUPPORT==1) +#include "rtl8192e/HalHWImg8192E_MAC.h" +#include "rtl8192e/HalHWImg8192E_RF.h" +#include "rtl8192e/HalHWImg8192E_BB.h" +#include "rtl8192e/HalHWImg8192E_FW.h" +#include "rtl8192e/Hal8192EReg.h" +#include "rtl8192e/phydm_RegConfig8192E.h" +#include "rtl8192e/phydm_RTL8192E.h" +#endif + +#if (RTL8723B_SUPPORT==1) +#include "rtl8723b/HalHWImg8723B_MAC.h" +#include "rtl8723b/HalHWImg8723B_RF.h" +#include "rtl8723b/HalHWImg8723B_BB.h" +#include "rtl8723b/HalHWImg8723B_FW.h" +#include "rtl8723b/HalHWImg8723B_MP.h" +#include "rtl8723b/Hal8723BReg.h" +#include "rtl8723b/phydm_RTL8723B.h" +#include "rtl8723b/phydm_RegConfig8723B.h" +#endif + +#if (RTL8812A_SUPPORT==1) +#include "rtl8812a/HalHWImg8812A_MAC.h" +#include "rtl8812a/HalHWImg8812A_RF.h" +#include "rtl8812a/HalHWImg8812A_BB.h" +#include "rtl8812a/HalHWImg8812A_FW.h" +#include "rtl8812a/phydm_RegConfig8812A.h" +#include "rtl8812a/phydm_RTL8812A.h" +#endif + + +#if (RTL8821A_SUPPORT==1) +#include "rtl8821a/HalHWImg8821A_MAC.h" +#include "rtl8821a/HalHWImg8821A_RF.h" +#include "rtl8821a/HalHWImg8821A_BB.h" +#include "rtl8821a/HalHWImg8821A_FW.h" +#include "rtl8821a/phydm_RegConfig8821A.h" +#include "rtl8821a/phydm_RTL8821A.h" +#endif + +#endif // __ODM_PRECOMP_H__ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_reg.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_reg.h new file mode 100755 index 000000000000..8deff91364f4 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_reg.h @@ -0,0 +1,208 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +//============================================================ +// File Name: odm_reg.h +// +// Description: +// +// This file is for general register definition. +// +// +//============================================================ +#ifndef __HAL_ODM_REG_H__ +#define __HAL_ODM_REG_H__ + +// +// Register Definition +// + +//MAC REG +#define ODM_BB_RESET 0x002 +#define ODM_DUMMY 0x4fe +#define RF_T_METER_OLD 0x24 +#define RF_T_METER_NEW 0x42 + +#define ODM_EDCA_VO_PARAM 0x500 +#define ODM_EDCA_VI_PARAM 0x504 +#define ODM_EDCA_BE_PARAM 0x508 +#define ODM_EDCA_BK_PARAM 0x50C +#define ODM_TXPAUSE 0x522 + +//BB REG +#define ODM_FPGA_PHY0_PAGE8 0x800 +#define ODM_PSD_SETTING 0x808 +#define ODM_AFE_SETTING 0x818 +#define ODM_TXAGC_B_6_18 0x830 +#define ODM_TXAGC_B_24_54 0x834 +#define ODM_TXAGC_B_MCS32_5 0x838 +#define ODM_TXAGC_B_MCS0_MCS3 0x83c +#define ODM_TXAGC_B_MCS4_MCS7 0x848 +#define ODM_TXAGC_B_MCS8_MCS11 0x84c +#define ODM_ANALOG_REGISTER 0x85c +#define ODM_RF_INTERFACE_OUTPUT 0x860 +#define ODM_TXAGC_B_MCS12_MCS15 0x868 +#define ODM_TXAGC_B_11_A_2_11 0x86c +#define ODM_AD_DA_LSB_MASK 0x874 +#define ODM_ENABLE_3_WIRE 0x88c +#define ODM_PSD_REPORT 0x8b4 +#define ODM_R_ANT_SELECT 0x90c +#define ODM_CCK_ANT_SELECT 0xa07 +#define ODM_CCK_PD_THRESH 0xa0a +#define ODM_CCK_RF_REG1 0xa11 +#define ODM_CCK_MATCH_FILTER 0xa20 +#define ODM_CCK_RAKE_MAC 0xa2e +#define ODM_CCK_CNT_RESET 0xa2d +#define ODM_CCK_TX_DIVERSITY 0xa2f +#define ODM_CCK_FA_CNT_MSB 0xa5b +#define ODM_CCK_FA_CNT_LSB 0xa5c +#define ODM_CCK_NEW_FUNCTION 0xa75 +#define ODM_OFDM_PHY0_PAGE_C 0xc00 +#define ODM_OFDM_RX_ANT 0xc04 +#define ODM_R_A_RXIQI 0xc14 +#define ODM_R_A_AGC_CORE1 0xc50 +#define ODM_R_A_AGC_CORE2 0xc54 +#define ODM_R_B_AGC_CORE1 0xc58 +#define ODM_R_AGC_PAR 0xc70 +#define ODM_R_HTSTF_AGC_PAR 0xc7c +#define ODM_TX_PWR_TRAINING_A 0xc90 +#define ODM_TX_PWR_TRAINING_B 0xc98 +#define ODM_OFDM_FA_CNT1 0xcf0 +#define ODM_OFDM_PHY0_PAGE_D 0xd00 +#define ODM_OFDM_FA_CNT2 0xda0 +#define ODM_OFDM_FA_CNT3 0xda4 +#define ODM_OFDM_FA_CNT4 0xda8 +#define ODM_TXAGC_A_6_18 0xe00 +#define ODM_TXAGC_A_24_54 0xe04 +#define ODM_TXAGC_A_1_MCS32 0xe08 +#define ODM_TXAGC_A_MCS0_MCS3 0xe10 +#define ODM_TXAGC_A_MCS4_MCS7 0xe14 +#define ODM_TXAGC_A_MCS8_MCS11 0xe18 +#define ODM_TXAGC_A_MCS12_MCS15 0xe1c + +//RF REG +#define ODM_GAIN_SETTING 0x00 +#define ODM_CHANNEL 0x18 +#define ODM_RF_T_METER 0x24 +#define ODM_RF_T_METER_92D 0x42 +#define ODM_RF_T_METER_88E 0x42 +#define ODM_RF_T_METER_92E 0x42 +#define ODM_RF_T_METER_8812 0x42 + +//Ant Detect Reg +#define ODM_DPDT 0x300 + +//PSD Init +#define ODM_PSDREG 0x808 + +//92D Path Div +#define PATHDIV_REG 0xB30 +#define PATHDIV_TRI 0xBA0 + + +// +// Bitmap Definition +// +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP)) +// TX AGC +#define rTxAGC_A_CCK11_CCK1_JAguar 0xc20 +#define rTxAGC_A_Ofdm18_Ofdm6_JAguar 0xc24 +#define rTxAGC_A_Ofdm54_Ofdm24_JAguar 0xc28 +#define rTxAGC_A_MCS3_MCS0_JAguar 0xc2c +#define rTxAGC_A_MCS7_MCS4_JAguar 0xc30 +#define rTxAGC_A_MCS11_MCS8_JAguar 0xc34 +#define rTxAGC_A_MCS15_MCS12_JAguar 0xc38 +#define rTxAGC_A_Nss1Index3_Nss1Index0_JAguar 0xc3c +#define rTxAGC_A_Nss1Index7_Nss1Index4_JAguar 0xc40 +#define rTxAGC_A_Nss2Index1_Nss1Index8_JAguar 0xc44 +#define rTxAGC_A_Nss2Index5_Nss2Index2_JAguar 0xc48 +#define rTxAGC_A_Nss2Index9_Nss2Index6_JAguar 0xc4c +#if defined(CONFIG_WLAN_HAL_8814AE) +#define rTxAGC_A_MCS19_MCS16_JAguar 0xcd8 +#define rTxAGC_A_MCS23_MCS20_JAguar 0xcdc +#define rTxAGC_A_Nss3Index3_Nss3Index0_JAguar 0xce0 +#define rTxAGC_A_Nss3Index7_Nss3Index4_JAguar 0xce4 +#define rTxAGC_A_Nss3Index9_Nss3Index8_JAguar 0xce8 +#endif +#define rTxAGC_B_CCK11_CCK1_JAguar 0xe20 +#define rTxAGC_B_Ofdm18_Ofdm6_JAguar 0xe24 +#define rTxAGC_B_Ofdm54_Ofdm24_JAguar 0xe28 +#define rTxAGC_B_MCS3_MCS0_JAguar 0xe2c +#define rTxAGC_B_MCS7_MCS4_JAguar 0xe30 +#define rTxAGC_B_MCS11_MCS8_JAguar 0xe34 +#define rTxAGC_B_MCS15_MCS12_JAguar 0xe38 +#define rTxAGC_B_Nss1Index3_Nss1Index0_JAguar 0xe3c +#define rTxAGC_B_Nss1Index7_Nss1Index4_JAguar 0xe40 +#define rTxAGC_B_Nss2Index1_Nss1Index8_JAguar 0xe44 +#define rTxAGC_B_Nss2Index5_Nss2Index2_JAguar 0xe48 +#define rTxAGC_B_Nss2Index9_Nss2Index6_JAguar 0xe4c +#if defined(CONFIG_WLAN_HAL_8814AE) +#define rTxAGC_B_MCS19_MCS16_JAguar 0xed8 +#define rTxAGC_B_MCS23_MCS20_JAguar 0xedc +#define rTxAGC_B_Nss3Index3_Nss3Index0_JAguar 0xee0 +#define rTxAGC_B_Nss3Index7_Nss3Index4_JAguar 0xee4 +#define rTxAGC_B_Nss3Index9_Nss3Index8_JAguar 0xee8 +#define rTxAGC_C_CCK11_CCK1_JAguar 0x1820 +#define rTxAGC_C_Ofdm18_Ofdm6_JAguar 0x1824 +#define rTxAGC_C_Ofdm54_Ofdm24_JAguar 0x1828 +#define rTxAGC_C_MCS3_MCS0_JAguar 0x182c +#define rTxAGC_C_MCS7_MCS4_JAguar 0x1830 +#define rTxAGC_C_MCS11_MCS8_JAguar 0x1834 +#define rTxAGC_C_MCS15_MCS12_JAguar 0x1838 +#define rTxAGC_C_Nss1Index3_Nss1Index0_JAguar 0x183c +#define rTxAGC_C_Nss1Index7_Nss1Index4_JAguar 0x1840 +#define rTxAGC_C_Nss2Index1_Nss1Index8_JAguar 0x1844 +#define rTxAGC_C_Nss2Index5_Nss2Index2_JAguar 0x1848 +#define rTxAGC_C_Nss2Index9_Nss2Index6_JAguar 0x184c +#define rTxAGC_C_MCS19_MCS16_JAguar 0x18d8 +#define rTxAGC_C_MCS23_MCS20_JAguar 0x18dc +#define rTxAGC_C_Nss3Index3_Nss3Index0_JAguar 0x18e0 +#define rTxAGC_C_Nss3Index7_Nss3Index4_JAguar 0x18e4 +#define rTxAGC_C_Nss3Index9_Nss3Index8_JAguar 0x18e8 +#define rTxAGC_D_CCK11_CCK1_JAguar 0x1a20 +#define rTxAGC_D_Ofdm18_Ofdm6_JAguar 0x1a24 +#define rTxAGC_D_Ofdm54_Ofdm24_JAguar 0x1a28 +#define rTxAGC_D_MCS3_MCS0_JAguar 0x1a2c +#define rTxAGC_D_MCS7_MCS4_JAguar 0x1a30 +#define rTxAGC_D_MCS11_MCS8_JAguar 0x1a34 +#define rTxAGC_D_MCS15_MCS12_JAguar 0x1a38 +#define rTxAGC_D_Nss1Index3_Nss1Index0_JAguar 0x1a3c +#define rTxAGC_D_Nss1Index7_Nss1Index4_JAguar 0x1a40 +#define rTxAGC_D_Nss2Index1_Nss1Index8_JAguar 0x1a44 +#define rTxAGC_D_Nss2Index5_Nss2Index2_JAguar 0x1a48 +#define rTxAGC_D_Nss2Index9_Nss2Index6_JAguar 0x1a4c +#define rTxAGC_D_MCS19_MCS16_JAguar 0x1ad8 +#define rTxAGC_D_MCS23_MCS20_JAguar 0x1adc +#define rTxAGC_D_Nss3Index3_Nss3Index0_JAguar 0x1ae0 +#define rTxAGC_D_Nss3Index7_Nss3Index4_JAguar 0x1ae4 +#define rTxAGC_D_Nss3Index9_Nss3Index8_JAguar 0x1ae8 +#endif + +#define bTxAGC_byte0_Jaguar 0xff +#define bTxAGC_byte1_Jaguar 0xff00 +#define bTxAGC_byte2_Jaguar 0xff0000 +#define bTxAGC_byte3_Jaguar 0xff000000 +#endif + +#define BIT_FA_RESET BIT0 + + + +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_types.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_types.h new file mode 100755 index 000000000000..ddeb1a8a8a1f --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/phydm_types.h @@ -0,0 +1,409 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __ODM_TYPES_H__ +#define __ODM_TYPES_H__ + + + + +#define ODM_RATEMCS15_SG 0x1c +#define ODM_RATEMCS32 0x20 + + +// CCK Rates, TxHT = 0 +#define ODM_RATE1M 0x00 +#define ODM_RATE2M 0x01 +#define ODM_RATE5_5M 0x02 +#define ODM_RATE11M 0x03 +// OFDM Rates, TxHT = 0 +#define ODM_RATE6M 0x04 +#define ODM_RATE9M 0x05 +#define ODM_RATE12M 0x06 +#define ODM_RATE18M 0x07 +#define ODM_RATE24M 0x08 +#define ODM_RATE36M 0x09 +#define ODM_RATE48M 0x0A +#define ODM_RATE54M 0x0B +// MCS Rates, TxHT = 1 +#define ODM_RATEMCS0 0x0C +#define ODM_RATEMCS1 0x0D +#define ODM_RATEMCS2 0x0E +#define ODM_RATEMCS3 0x0F +#define ODM_RATEMCS4 0x10 +#define ODM_RATEMCS5 0x11 +#define ODM_RATEMCS6 0x12 +#define ODM_RATEMCS7 0x13 +#define ODM_RATEMCS8 0x14 +#define ODM_RATEMCS9 0x15 +#define ODM_RATEMCS10 0x16 +#define ODM_RATEMCS11 0x17 +#define ODM_RATEMCS12 0x18 +#define ODM_RATEMCS13 0x19 +#define ODM_RATEMCS14 0x1A +#define ODM_RATEMCS15 0x1B +#define ODM_RATEMCS16 0x1C +#define ODM_RATEMCS17 0x1D +#define ODM_RATEMCS18 0x1E +#define ODM_RATEMCS19 0x1F +#define ODM_RATEMCS20 0x20 +#define ODM_RATEMCS21 0x21 +#define ODM_RATEMCS22 0x22 +#define ODM_RATEMCS23 0x23 +#define ODM_RATEMCS24 0x24 +#define ODM_RATEMCS25 0x25 +#define ODM_RATEMCS26 0x26 +#define ODM_RATEMCS27 0x27 +#define ODM_RATEMCS28 0x28 +#define ODM_RATEMCS29 0x29 +#define ODM_RATEMCS30 0x2A +#define ODM_RATEMCS31 0x2B +#define ODM_RATEVHTSS1MCS0 0x2C +#define ODM_RATEVHTSS1MCS1 0x2D +#define ODM_RATEVHTSS1MCS2 0x2E +#define ODM_RATEVHTSS1MCS3 0x2F +#define ODM_RATEVHTSS1MCS4 0x30 +#define ODM_RATEVHTSS1MCS5 0x31 +#define ODM_RATEVHTSS1MCS6 0x32 +#define ODM_RATEVHTSS1MCS7 0x33 +#define ODM_RATEVHTSS1MCS8 0x34 +#define ODM_RATEVHTSS1MCS9 0x35 +#define ODM_RATEVHTSS2MCS0 0x36 +#define ODM_RATEVHTSS2MCS1 0x37 +#define ODM_RATEVHTSS2MCS2 0x38 +#define ODM_RATEVHTSS2MCS3 0x39 +#define ODM_RATEVHTSS2MCS4 0x3A +#define ODM_RATEVHTSS2MCS5 0x3B +#define ODM_RATEVHTSS2MCS6 0x3C +#define ODM_RATEVHTSS2MCS7 0x3D +#define ODM_RATEVHTSS2MCS8 0x3E +#define ODM_RATEVHTSS2MCS9 0x3F +#define ODM_RATEVHTSS3MCS0 0x40 +#define ODM_RATEVHTSS3MCS1 0x41 +#define ODM_RATEVHTSS3MCS2 0x42 +#define ODM_RATEVHTSS3MCS3 0x43 +#define ODM_RATEVHTSS3MCS4 0x44 +#define ODM_RATEVHTSS3MCS5 0x45 +#define ODM_RATEVHTSS3MCS6 0x46 +#define ODM_RATEVHTSS3MCS7 0x47 +#define ODM_RATEVHTSS3MCS8 0x48 +#define ODM_RATEVHTSS3MCS9 0x49 +#define ODM_RATEVHTSS4MCS0 0x4A +#define ODM_RATEVHTSS4MCS1 0x4B +#define ODM_RATEVHTSS4MCS2 0x4C +#define ODM_RATEVHTSS4MCS3 0x4D +#define ODM_RATEVHTSS4MCS4 0x4E +#define ODM_RATEVHTSS4MCS5 0x4F +#define ODM_RATEVHTSS4MCS6 0x50 +#define ODM_RATEVHTSS4MCS7 0x51 +#define ODM_RATEVHTSS4MCS8 0x52 +#define ODM_RATEVHTSS4MCS9 0x53 + +// +// Define Different SW team support +// +#define ODM_AP 0x01 //BIT0 +#define ODM_ADSL 0x02 //BIT1 +#define ODM_CE 0x04 //BIT2 +#define ODM_WIN 0x08 //BIT3 + +#define DM_ODM_SUPPORT_TYPE ODM_CE + +// Deifne HW endian support +#define ODM_ENDIAN_BIG 0 +#define ODM_ENDIAN_LITTLE 1 + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define GET_PDM_ODM(__pAdapter) ((PDM_ODM_T)(&((GET_HAL_DATA(__pAdapter))->DM_OutSrc))) +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) +#define GET_PDM_ODM(__pAdapter) ((PDM_ODM_T)(&((GET_HAL_DATA(__pAdapter))->odmpriv))) +#endif + +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +#define RT_PCI_INTERFACE 1 +#define RT_USB_INTERFACE 2 +#define RT_SDIO_INTERFACE 3 +#endif + +typedef enum _HAL_STATUS{ + HAL_STATUS_SUCCESS, + HAL_STATUS_FAILURE, + /*RT_STATUS_PENDING, + RT_STATUS_RESOURCE, + RT_STATUS_INVALID_CONTEXT, + RT_STATUS_INVALID_PARAMETER, + RT_STATUS_NOT_SUPPORT, + RT_STATUS_OS_API_FAILED,*/ +}HAL_STATUS,*PHAL_STATUS; + +#if( DM_ODM_SUPPORT_TYPE == ODM_AP) +#define MP_DRIVER 0 +#endif +#if(DM_ODM_SUPPORT_TYPE != ODM_WIN) + +#define VISTA_USB_RX_REVISE 0 + +// +// Declare for ODM spin lock defintion temporarily fro compile pass. +// +typedef enum _RT_SPINLOCK_TYPE{ + RT_TX_SPINLOCK = 1, + RT_RX_SPINLOCK = 2, + RT_RM_SPINLOCK = 3, + RT_CAM_SPINLOCK = 4, + RT_SCAN_SPINLOCK = 5, + RT_LOG_SPINLOCK = 7, + RT_BW_SPINLOCK = 8, + RT_CHNLOP_SPINLOCK = 9, + RT_RF_OPERATE_SPINLOCK = 10, + RT_INITIAL_SPINLOCK = 11, + RT_RF_STATE_SPINLOCK = 12, // For RF state. Added by Bruce, 2007-10-30. +#if VISTA_USB_RX_REVISE + RT_USBRX_CONTEXT_SPINLOCK = 13, + RT_USBRX_POSTPROC_SPINLOCK = 14, // protect data of Adapter->IndicateW/ IndicateR +#endif + //Shall we define Ndis 6.2 SpinLock Here ? + RT_PORT_SPINLOCK=16, + RT_VNIC_SPINLOCK=17, + RT_HVL_SPINLOCK=18, + RT_H2C_SPINLOCK = 20, // For H2C cmd. Added by tynli. 2009.11.09. + + RT_BTData_SPINLOCK=25, + + RT_WAPI_OPTION_SPINLOCK=26, + RT_WAPI_RX_SPINLOCK=27, + + // add for 92D CCK control issue + RT_CCK_PAGEA_SPINLOCK = 28, + RT_BUFFER_SPINLOCK = 29, + RT_CHANNEL_AND_BANDWIDTH_SPINLOCK = 30, + RT_GEN_TEMP_BUF_SPINLOCK = 31, + RT_AWB_SPINLOCK = 32, + RT_FW_PS_SPINLOCK = 33, + RT_HW_TIMER_SPIN_LOCK = 34, + RT_MPT_WI_SPINLOCK = 35, + RT_P2P_SPIN_LOCK = 36, // Protect P2P context + RT_DBG_SPIN_LOCK = 37, + RT_IQK_SPINLOCK = 38, + RT_PENDED_OID_SPINLOCK = 39, + RT_CHNLLIST_SPINLOCK = 40, + RT_INDIC_SPINLOCK = 41, //protect indication + RT_RFD_SPINLOCK = 42, + RT_LAST_SPINLOCK, +}RT_SPINLOCK_TYPE; + +#endif + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #define STA_INFO_T RT_WLAN_STA + #define PSTA_INFO_T PRT_WLAN_STA + +// typedef unsigned long u4Byte,*pu4Byte; +#define CONFIG_HW_ANTENNA_DIVERSITY +#define CONFIG_SW_ANTENNA_DIVERSITY + +#elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + + // To let ADSL/AP project compile ok; it should be removed after all conflict are solved. Added by Annie, 2011-10-07. + #define ADSL_AP_BUILD_WORKAROUND + #define AP_BUILD_WORKAROUND + + //2 [ Configure Antenna Diversity ] +#if defined(CONFIG_RTL_8881A_ANT_SWITCH) || defined(CONFIG_SLOT_0_ANT_SWITCH) || defined(CONFIG_SLOT_1_ANT_SWITCH) + #define CONFIG_HW_ANTENNA_DIVERSITY + #define ODM_EVM_ENHANCE_ANTDIV + + //---------- + #if(!defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_2G_CGCS_RX_DIVERSITY) && !defined(CONFIG_2G_CG_TRX_DIVERSITY) && !defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) + #define CONFIG_NO_2G_DIVERSITY + #endif + + #ifdef CONFIG_NO_5G_DIVERSITY_8881A + #define CONFIG_NO_5G_DIVERSITY + #elif defined(CONFIG_5G_CGCS_RX_DIVERSITY_8881A) + #define CONFIG_5G_CGCS_RX_DIVERSITY + #elif defined(CONFIG_5G_CG_TRX_DIVERSITY_8881A) + #define CONFIG_5G_CG_TRX_DIVERSITY + #endif + + #if(!defined(CONFIG_NO_5G_DIVERSITY) && !defined(CONFIG_5G_CGCS_RX_DIVERSITY) && !defined(CONFIG_5G_CG_TRX_DIVERSITY) && !defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) + #define CONFIG_NO_5G_DIVERSITY + #endif + //---------- + #if ( defined(CONFIG_NO_2G_DIVERSITY) && defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_NOT_SUPPORT_ANTDIV + #elif( !defined(CONFIG_NO_2G_DIVERSITY) && defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_2G_SUPPORT_ANTDIV + #elif( defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_5G_SUPPORT_ANTDIV + #elif( !defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_2G5G_SUPPORT_ANTDIV + #endif + //---------- +#endif + #ifdef AP_BUILD_WORKAROUND + #include "../typedef.h" + #else + typedef void VOID,*PVOID; + typedef unsigned char BOOLEAN,*PBOOLEAN; + typedef unsigned char u1Byte,*pu1Byte; + typedef unsigned short u2Byte,*pu2Byte; + typedef unsigned int u4Byte,*pu4Byte; + typedef unsigned long long u8Byte,*pu8Byte; +#if 1 +/* In ARM platform, system would use the type -- "char" as "unsigned char" + * And we only use s1Byte/ps1Byte as INT8 now, so changes the type of s1Byte.*/ + typedef signed char s1Byte,*ps1Byte; +#else + typedef char s1Byte,*ps1Byte; +#endif + typedef short s2Byte,*ps2Byte; + typedef long s4Byte,*ps4Byte; + typedef long long s8Byte,*ps8Byte; + #endif + + typedef struct rtl8192cd_priv *prtl8192cd_priv; + typedef struct stat_info STA_INFO_T,*PSTA_INFO_T; + typedef struct timer_list RT_TIMER, *PRT_TIMER; + typedef void * RT_TIMER_CALL_BACK; + +#ifdef CONFIG_PCI_HCI + #define DEV_BUS_TYPE RT_PCI_INTERFACE +#endif + + #define _TRUE 1 + #define _FALSE 0 + +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + + // To let ADSL/AP project compile ok; it should be removed after all conflict are solved. Added by Annie, 2011-10-07. + #define ADSL_AP_BUILD_WORKAROUND + #define ADSL_BUILD_WORKAROUND + // + + typedef unsigned char BOOLEAN,*PBOOLEAN; + typedef unsigned char u1Byte,*pu1Byte; + typedef unsigned short u2Byte,*pu2Byte; + typedef unsigned int u4Byte,*pu4Byte; + typedef unsigned long long u8Byte,*pu8Byte; +#if 1 +/* In ARM platform, system would use the type -- "char" as "unsigned char" + * And we only use s1Byte/ps1Byte as INT8 now, so changes the type of s1Byte.*/ + typedef signed char s1Byte,*ps1Byte; +#else + typedef char s1Byte,*ps1Byte; +#endif + typedef short s2Byte,*ps2Byte; + typedef long s4Byte,*ps4Byte; + typedef long long s8Byte,*ps8Byte; + + typedef struct rtl8192cd_priv *prtl8192cd_priv; + typedef struct stat_info STA_INFO_T,*PSTA_INFO_T; + typedef struct timer_list RT_TIMER, *PRT_TIMER; + typedef void * RT_TIMER_CALL_BACK; + + #define DEV_BUS_TYPE RT_PCI_INTERFACE + + #define _TRUE 1 + #define _FALSE 0 + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include + +#if 0 + typedef u8 u1Byte, *pu1Byte; + typedef u16 u2Byte,*pu2Byte; + typedef u32 u4Byte,*pu4Byte; + typedef u64 u8Byte,*pu8Byte; + typedef s8 s1Byte,*ps1Byte; + typedef s16 s2Byte,*ps2Byte; + typedef s32 s4Byte,*ps4Byte; + typedef s64 s8Byte,*ps8Byte; +#else + #define u1Byte u8 + #define pu1Byte u8* + + #define u2Byte u16 + #define pu2Byte u16* + + #define u4Byte u32 + #define pu4Byte u32* + + #define u8Byte u64 + #define pu8Byte u64* + + #define s1Byte s8 + #define ps1Byte s8* + + #define s2Byte s16 + #define ps2Byte s16* + + #define s4Byte s32 + #define ps4Byte s32* + + #define s8Byte s64 + #define ps8Byte s64* + +#endif + #ifdef CONFIG_USB_HCI + #define DEV_BUS_TYPE RT_USB_INTERFACE + #elif defined(CONFIG_PCI_HCI) + #define DEV_BUS_TYPE RT_PCI_INTERFACE + #elif defined(CONFIG_SDIO_HCI) + #define DEV_BUS_TYPE RT_SDIO_INTERFACE + #elif defined(CONFIG_GSPI_HCI) + #define DEV_BUS_TYPE RT_SDIO_INTERFACE + #endif + + + #if defined(CONFIG_LITTLE_ENDIAN) + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #elif defined (CONFIG_BIG_ENDIAN) + #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG + #endif + + typedef struct timer_list RT_TIMER, *PRT_TIMER; + typedef void * RT_TIMER_CALL_BACK; + #define STA_INFO_T struct sta_info + #define PSTA_INFO_T struct sta_info * + + + + #define TRUE _TRUE + #define FALSE _FALSE + + + #define SET_TX_DESC_ANTSEL_A_88E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 1, __Value) + #define SET_TX_DESC_ANTSEL_B_88E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 25, 1, __Value) + #define SET_TX_DESC_ANTSEL_C_88E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 29, 1, __Value) + + //define useless flag to avoid compile warning + #define USE_WORKITEM 0 + #define FOR_BRAZIL_PRETEST 0 + #define FPGA_TWO_MAC_VERIFICATION 0 + #define RTL8881A_SUPPORT 0 +#endif + +#define READ_NEXT_PAIR(v1, v2, i) do { if (i+2 >= ArrayLen) break; i += 2; v1 = Array[i]; v2 = Array[i+1]; } while(0) +#define COND_ELSE 2 +#define COND_ENDIF 3 + +#endif // __ODM_TYPES_H__ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_BB.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_BB.c index 89e1ae23755b..e528518746c1 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_BB.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_BB.c @@ -18,8 +18,8 @@ * ******************************************************************************/ - -#include "../odm_precomp.h" +#include "Mp_Precomp.h" +#include "../phydm_precomp.h" #if (RTL8723B_SUPPORT == 1) static BOOLEAN @@ -252,72 +252,69 @@ ODM_ReadAndConfig_MP_8723B_AGC_TAB( ) { u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; +//ask by Luke.Lee u4Byte ArrayLen = sizeof(Array_MP_8723B_AGC_TAB)/sizeof(u4Byte); pu4Byte Array = Array_MP_8723B_AGC_TAB; ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8723B_AGC_TAB\n")); - for (i = 0; i < ArrayLen; i += 2 ) - { - u4Byte v1 = Array[i]; - u4Byte v2 = Array[i+1]; - - // This (offset, data) pair doesn't care the condition. - if ( v1 < 0x40000000 ) - { - odm_ConfigBB_AGC_8723B(pDM_Odm, v1, bMaskDWord, v2); - continue; - } - else - { // This line is the beginning of branch. - BOOLEAN bMatched = TRUE; - u1Byte cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - - if (cCond == COND_ELSE) { // ELSE, ENDIF - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } else if ( ! CheckPositive(pDM_Odm, v1, v2) ) { - bMatched = FALSE; - READ_NEXT_PAIR(v1, v2, i); - READ_NEXT_PAIR(v1, v2, i); - } else { - READ_NEXT_PAIR(v1, v2, i); - if ( ! CheckNegative(pDM_Odm, v1, v2) ) - bMatched = FALSE; - else - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } - - if ( bMatched == FALSE ) - { // Condition isn't matched. Discard the following (offset, data) pairs. - while (v1 < 0x40000000 && i < ArrayLen -2) - READ_NEXT_PAIR(v1, v2, i); - - i -= 2; // prevent from for-loop += 2 - } - else // Configure matched pairs and skip to end of if-else. - { - while (v1 < 0x40000000 && i < ArrayLen-2) { - odm_ConfigBB_AGC_8723B(pDM_Odm, v1, bMaskDWord, v2); - READ_NEXT_PAIR(v1, v2, i); - } - - // Keeps reading until ENDIF. - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - while (cCond != COND_ENDIF && i < ArrayLen-2) { - READ_NEXT_PAIR(v1, v2, i); - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - } - } - } - } + while(( i+1) < ArrayLen) + { + u4Byte v1 = Array[i]; + u4Byte v2 = Array[i+1]; + + if(v1 & (BIT31|BIT30)) //positive & negative condition + { + if(v1 & BIT31) // positive condition + { + cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); + if(cCond == COND_ENDIF) //end + { + bMatched = TRUE; + bSkipped = FALSE; + } + else if(cCond == COND_ELSE) //else + { + bMatched = bSkipped?FALSE:TRUE; + } + else //if , else if + { + if(bSkipped) + bMatched = FALSE; + else + { + if(CheckPositive(pDM_Odm, v1, v2)) + { + bMatched = TRUE; + bSkipped = TRUE; + } + else + { + bMatched = FALSE; + bSkipped = FALSE; + } + } + } + } + else if(v1 & BIT30){ //negative condition + //do nothing + } + } + else + { + if(bMatched) + odm_ConfigBB_AGC_8723B(pDM_Odm, v1, bMaskDWord, v2); + } + i = i + 2; + } } u4Byte ODM_GetVersion_MP_8723B_AGC_TAB(void) { - return 11; + return 12; } /****************************************************************************** @@ -527,72 +524,69 @@ ODM_ReadAndConfig_MP_8723B_PHY_REG( ) { u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; +//ask by Luke.Lee u4Byte ArrayLen = sizeof(Array_MP_8723B_PHY_REG)/sizeof(u4Byte); pu4Byte Array = Array_MP_8723B_PHY_REG; ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8723B_PHY_REG\n")); - for (i = 0; i < ArrayLen; i += 2 ) - { - u4Byte v1 = Array[i]; - u4Byte v2 = Array[i+1]; - - // This (offset, data) pair doesn't care the condition. - if ( v1 < 0x40000000 ) - { - odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2); - continue; - } - else - { // This line is the beginning of branch. - BOOLEAN bMatched = TRUE; - u1Byte cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - - if (cCond == COND_ELSE) { // ELSE, ENDIF - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } else if ( ! CheckPositive(pDM_Odm, v1, v2) ) { - bMatched = FALSE; - READ_NEXT_PAIR(v1, v2, i); - READ_NEXT_PAIR(v1, v2, i); - } else { - READ_NEXT_PAIR(v1, v2, i); - if ( ! CheckNegative(pDM_Odm, v1, v2) ) - bMatched = FALSE; - else - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } - - if ( bMatched == FALSE ) - { // Condition isn't matched. Discard the following (offset, data) pairs. - while (v1 < 0x40000000 && i < ArrayLen -2) - READ_NEXT_PAIR(v1, v2, i); - - i -= 2; // prevent from for-loop += 2 - } - else // Configure matched pairs and skip to end of if-else. - { - while (v1 < 0x40000000 && i < ArrayLen-2) { - odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2); - READ_NEXT_PAIR(v1, v2, i); - } - - // Keeps reading until ENDIF. - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - while (cCond != COND_ENDIF && i < ArrayLen-2) { - READ_NEXT_PAIR(v1, v2, i); - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - } - } - } - } + while(( i+1) < ArrayLen) + { + u4Byte v1 = Array[i]; + u4Byte v2 = Array[i+1]; + + if(v1 & (BIT31|BIT30)) //positive & negative condition + { + if(v1 & BIT31) // positive condition + { + cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); + if(cCond == COND_ENDIF) //end + { + bMatched = TRUE; + bSkipped = FALSE; + } + else if(cCond == COND_ELSE) //else + { + bMatched = bSkipped?FALSE:TRUE; + } + else //if , else if + { + if(bSkipped) + bMatched = FALSE; + else + { + if(CheckPositive(pDM_Odm, v1, v2)) + { + bMatched = TRUE; + bSkipped = TRUE; + } + else + { + bMatched = FALSE; + bSkipped = FALSE; + } + } + } + } + else if(v1 & BIT30){ //negative condition + //do nothing + } + } + else + { + if(bMatched) + odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2); + } + i = i + 2; + } } u4Byte ODM_GetVersion_MP_8723B_PHY_REG(void) { - return 11; + return 12; } /****************************************************************************** diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_FW.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_FW.c index 592d15828a78..d362242109a4 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_FW.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_FW.c @@ -18,8 +18,8 @@ * ******************************************************************************/ -//#include "Mp_Precomp.h" -#include "../odm_precomp.h" +#include "Mp_Precomp.h" +#include "../phydm_precomp.h" #if (RTL8723B_SUPPORT == 1) #ifdef CONFIG_AP_WOWLAN @@ -1604,16 +1604,16 @@ ODM_ReadFirmware_MP_8723B_FW_BT( } -// v29 20140605 by Isaachsu +// v31.00 20140813 by Isaachsu u1Byte Array_MP_8723B_FW_NIC[] = { -0x01, 0x53, 0x10, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x06, 0x05, 0x10, 0x58, 0x9C, 0x6A, 0x00, 0x00, -0xF8, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x45, 0xED, 0x02, 0x77, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x79, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x78, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x53, 0x10, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x08, 0x13, 0x23, 0x37, 0x44, 0x6D, 0x00, 0x00, +0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x45, 0xED, 0x02, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x80, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x80, 0x15, 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, 0x02, 0x78, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7F, 0xE7, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x88, 0x00, 0x15, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x15, 0xF0, 0x0F, +0x00, 0x00, 0x00, 0x02, 0x80, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x87, 0xDE, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x8F, 0xD1, 0x15, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x15, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x05, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x05, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x10, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x10, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, @@ -1711,1611 +1711,1654 @@ u1Byte Array_MP_8723B_FW_NIC[] = { 0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, -0x41, 0xA1, 0xEC, 0x00, 0x41, 0xA1, 0xED, 0x00, 0x41, 0xA1, 0xEE, 0x00, 0x41, 0xA1, 0xF2, 0x00, -0x01, 0x70, 0x00, 0x41, 0xA1, 0xF3, 0x00, 0x41, 0xA1, 0xF4, 0x00, 0x41, 0xA2, 0x16, 0x00, 0x00, -0x5F, 0xF8, 0x67, 0xE8, 0x6F, 0xE6, 0x7F, 0x67, 0xF1, 0xBF, 0xEF, 0x44, 0x20, 0xFD, 0x7F, 0x67, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x82, 0x75, 0x83, 0x00, 0xED, 0x12, 0xAA, 0x41, -0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xCC, 0xEF, -0xF0, 0x90, 0xA1, 0xCE, 0xEB, 0xF0, 0xED, 0x60, 0x02, 0xE1, 0x5B, 0x90, 0x07, 0x6E, 0xE0, 0x44, -0x08, 0xF0, 0x12, 0x9D, 0x0F, 0x90, 0xA1, 0xCE, 0xE0, 0x70, 0x3B, 0xD1, 0x96, 0x90, 0xA1, 0xCC, -0xE0, 0x70, 0x2D, 0x12, 0xAA, 0x2F, 0x70, 0x12, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0x74, 0x02, 0xFE, -0xEC, 0xF1, 0xE1, 0xF1, 0xB6, 0xEF, 0x54, 0xFE, 0x80, 0x11, 0x12, 0x37, 0x4E, 0xE4, 0xFE, 0x74, -0x80, 0xFF, 0xE4, 0xEC, 0xF1, 0xE1, 0xF1, 0xB6, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x64, 0xD1, 0xA0, -0x7F, 0x4E, 0xF1, 0xFA, 0xE1, 0xA8, 0xD1, 0x96, 0x90, 0xA1, 0xCC, 0xE0, 0x70, 0x10, 0x12, 0x8A, -0x2E, 0xE4, 0xFF, 0xFE, 0xEC, 0xF1, 0xE1, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, 0xF1, 0xF2, -0xF1, 0xE7, 0x44, 0x01, 0xFD, 0x7F, 0x4F, 0xD1, 0xA0, 0x12, 0xA9, 0xF9, 0x74, 0x66, 0xFF, 0xEC, -0xF1, 0xE1, 0x7F, 0x30, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x12, 0x65, 0x50, 0x54, 0xFC, 0xFF, 0xEF, -0x44, 0x01, 0xFF, 0xEC, 0xF1, 0xE1, 0x12, 0x66, 0xAA, 0x80, 0x56, 0x90, 0x07, 0x6E, 0xE0, 0x54, -0xF7, 0xF0, 0x12, 0x9D, 0x17, 0x90, 0xA1, 0xCC, 0xE0, 0x70, 0x3B, 0x90, 0xA1, 0xCE, 0xE0, 0x60, -0x09, 0xD1, 0x96, 0x12, 0x8A, 0x2E, 0xE4, 0xFF, 0x80, 0x21, 0x7F, 0x67, 0xF1, 0xBF, 0xEF, 0x54, -0xDF, 0xFD, 0x7F, 0x67, 0xD1, 0xA0, 0x12, 0xAA, 0x2F, 0x70, 0x0B, 0x12, 0x37, 0x4E, 0xE4, 0x74, -0x80, 0xFF, 0x74, 0x02, 0x80, 0x05, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0xFE, 0xEC, 0xF1, 0xE1, 0x7F, -0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, 0xF1, 0xF2, 0xF1, 0xE7, 0x54, 0xFE, 0xFD, 0x7F, 0x4F, 0xD1, -0xA0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x7F, 0x64, 0xD3, -0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x82, 0x75, 0x83, 0x00, 0xE0, 0x90, 0xA2, 0x0C, 0x12, -0xAA, 0x41, 0x90, 0xA2, 0x0C, 0xE0, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA1, 0x9D, 0xB1, -0x71, 0x90, 0xAA, 0xB9, 0x02, 0x08, 0x6D, 0xFD, 0x7F, 0x4E, 0xD1, 0xA0, 0x7F, 0x4F, 0xF1, 0xBF, -0xEF, 0x22, 0x7F, 0x4E, 0xF1, 0xBF, 0xEF, 0x54, 0x7F, 0x22, 0xF1, 0xBF, 0xEF, 0x44, 0x80, 0x22, -0x90, 0xA0, 0x2C, 0xE0, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0x75, 0xF0, 0x0E, 0x90, 0xA0, 0x39, 0x12, -0x45, 0xA9, 0xE0, 0xFE, 0x75, 0xF0, 0x0E, 0xEF, 0x90, 0xA0, 0x38, 0x12, 0x45, 0xA9, 0xE0, 0x90, -0xA1, 0xB2, 0xF0, 0x90, 0xA1, 0xB1, 0xEE, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0xD3, -0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xAD, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA1, -0xB1, 0xE0, 0xF5, 0x3B, 0xA3, 0xE0, 0xF5, 0x3C, 0x12, 0x36, 0x3E, 0x90, 0xA1, 0xAD, 0x12, 0x8F, -0xA0, 0xA3, 0xA3, 0xA3, 0x74, 0x05, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA0, 0x2C, 0xE0, -0x30, 0xE0, 0x5D, 0x90, 0xA0, 0x2E, 0xE0, 0x70, 0x2A, 0x7D, 0x16, 0x7F, 0x6F, 0x31, 0x1D, 0x91, -0x1F, 0x51, 0x47, 0x54, 0x07, 0x75, 0xF0, 0x0E, 0x11, 0xC1, 0x51, 0x47, 0x54, 0x07, 0x12, 0xA5, -0xFA, 0xE0, 0x44, 0x01, 0x12, 0x93, 0xC3, 0xA3, 0x74, 0x03, 0x11, 0x27, 0x90, 0xA0, 0x2E, 0x74, -0x01, 0xF0, 0x22, 0x90, 0xA0, 0x2E, 0xE0, 0x64, 0x01, 0x70, 0x23, 0x90, 0xA0, 0x2C, 0xE0, 0x12, -0xA5, 0xF5, 0xE0, 0x30, 0xE0, 0x18, 0x75, 0xF0, 0x0E, 0xEF, 0x11, 0xC1, 0xE4, 0x90, 0xA1, 0xB1, -0xF0, 0xA3, 0x74, 0x03, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x01, 0x2F, 0x31, 0x28, -0x22, 0x90, 0xA0, 0x3B, 0x12, 0x45, 0xA9, 0xE0, 0xFF, 0x7E, 0x00, 0x7D, 0x01, 0xD3, 0x10, 0xAF, -0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xB3, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, -0x04, 0x1D, 0xE0, 0x60, 0x1C, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, 0xB8, 0xF0, 0x7D, 0x14, 0x91, -0x1B, 0xBF, 0x01, 0x02, 0x91, 0xFC, 0x90, 0xA1, 0xB8, 0xE0, 0xFF, 0x7D, 0x15, 0x31, 0x1D, 0x80, -0x02, 0x91, 0xFC, 0xF1, 0x0A, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA0, 0x3B, 0x12, -0x45, 0xA9, 0xE0, 0xFF, 0x7E, 0x00, 0xE4, 0xFD, 0x11, 0xCD, 0xE4, 0xFD, 0xFF, 0x90, 0x05, 0x22, -0xEF, 0xF0, 0x90, 0x9D, 0x97, 0xED, 0xF0, 0x22, 0x90, 0xA0, 0x2C, 0xE0, 0xFF, 0xC3, 0x13, 0xFE, -0xEF, 0x54, 0xF1, 0xFF, 0xEE, 0x04, 0x54, 0x07, 0x25, 0xE0, 0x4F, 0xF0, 0xA3, 0xE0, 0xFF, 0x12, -0xA9, 0xD2, 0xB5, 0x07, 0x04, 0xEE, 0x54, 0xF1, 0xF0, 0x11, 0x00, 0xE4, 0x90, 0xA0, 0x2E, 0xF0, -0x91, 0x1F, 0x12, 0xA9, 0xD2, 0x12, 0xA9, 0x6D, 0xE0, 0xFA, 0x75, 0xF0, 0x0E, 0xED, 0xF1, 0xB6, -0xFC, 0x54, 0x03, 0xFD, 0xEC, 0x13, 0x13, 0x54, 0x07, 0xFB, 0xEE, 0x12, 0xAA, 0x69, 0xAF, 0x02, -0x12, 0xA4, 0x4F, 0x51, 0x47, 0x54, 0x07, 0x75, 0xF0, 0x0E, 0xF1, 0xB6, 0x12, 0xA9, 0xBE, 0xFD, -0x51, 0x4E, 0x51, 0x47, 0x54, 0x07, 0xFF, 0x75, 0xF0, 0x0E, 0x90, 0xA0, 0x3A, 0x12, 0x45, 0xA9, -0xE0, 0x04, 0xF0, 0x75, 0xF0, 0x0E, 0xEF, 0x31, 0x0C, 0x51, 0x47, 0x54, 0x07, 0xFD, 0xE4, 0xFF, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xE4, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xE4, -0xA3, 0xF0, 0x90, 0xA1, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x02, 0x40, 0x02, 0x41, 0x42, 0x90, 0xA1, -0xE5, 0xE0, 0xFE, 0x12, 0xA5, 0xC2, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0xA9, 0x84, 0xE0, 0x90, 0xA1, -0xE7, 0xF0, 0x90, 0xA1, 0xE4, 0xE0, 0x60, 0x24, 0x90, 0xA1, 0xE7, 0xE0, 0xFF, 0x75, 0xF0, 0x0E, -0xEE, 0x12, 0xA5, 0xBC, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xA1, 0xE6, 0xE0, 0xD0, 0x82, 0xD0, 0x83, -0x12, 0xA9, 0x15, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0x80, 0x20, 0x12, 0xA9, 0xDC, 0x75, -0xF0, 0x0E, 0x12, 0xA5, 0xBC, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xA1, 0xE6, 0xE0, 0xD0, 0x82, 0xD0, -0x83, 0x12, 0xA9, 0x15, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0xA1, 0xE7, 0xF0, -0x12, 0xA9, 0xDC, 0x12, 0xA5, 0xC2, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xA1, 0xE6, 0xE0, 0xD0, 0x82, -0xD0, 0x83, 0x75, 0xF0, 0x03, 0x12, 0xA9, 0x84, 0xEF, 0xF0, 0x90, 0xA1, 0xE6, 0xE0, 0x04, 0xF0, -0x21, 0xB2, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA0, 0x2C, 0xE0, 0xC3, 0x13, 0x22, 0xD3, 0x10, -0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x0F, 0xED, 0xF0, 0xEF, 0x14, 0x60, 0x02, 0x61, 0x0D, -0x90, 0x06, 0x03, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0xA2, 0x0F, 0xE0, 0xC4, 0x33, 0x54, 0xE0, 0xFF, -0x90, 0x04, 0x42, 0xE0, 0x54, 0x9F, 0x4F, 0xFF, 0xF0, 0x90, 0xA1, 0x60, 0x12, 0x08, 0x79, 0x00, -0x00, 0x00, 0x01, 0x90, 0xA1, 0x64, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x7F, 0x00, 0x7E, -0x08, 0x71, 0xD7, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0xA1, 0x64, 0x12, 0x08, 0x79, -0x00, 0x00, 0x00, 0x01, 0x71, 0xD3, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x10, 0x12, 0xA9, 0x23, -0x78, 0x01, 0x12, 0x08, 0x47, 0x78, 0x04, 0xF1, 0xC6, 0x7F, 0x00, 0x7E, 0x0A, 0x71, 0xD7, 0x12, -0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x12, 0xA9, 0x23, 0x78, 0x0A, 0xF1, 0xC6, 0x7F, 0x00, 0x7E, -0x0D, 0x71, 0xD7, 0x12, 0x08, 0x79, 0x0C, 0x00, 0x00, 0x00, 0x12, 0xA9, 0x23, 0x78, 0x1A, 0xF1, -0xC6, 0x7F, 0x18, 0x7E, 0x08, 0x71, 0xD7, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0xA1, -0x64, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xD9, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, -0x00, 0x90, 0xA1, 0x52, 0x12, 0x08, 0x79, 0x00, 0x00, 0x04, 0x00, 0x80, 0x58, 0x90, 0x06, 0x03, -0xE0, 0x44, 0x04, 0xF0, 0x90, 0xA1, 0x60, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0xA1, -0x64, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x7E, 0x08, 0x71, 0xD7, 0x12, 0x08, -0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0xA1, 0x64, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x71, -0xD3, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0xA1, 0x64, 0x12, 0x08, 0x79, 0x00, 0x00, -0x0C, 0x00, 0xF1, 0xD9, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0xA1, 0x52, 0x12, 0x08, -0x79, 0x00, 0x00, 0x0C, 0x00, 0x7D, 0x18, 0x7C, 0x00, 0xE4, 0xFF, 0x12, 0xA3, 0xD7, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0x5E, 0xEE, 0xF0, 0xA3, -0xEF, 0xF0, 0x12, 0x37, 0x4E, 0x90, 0xA1, 0x68, 0x12, 0x08, 0x6D, 0x90, 0xA1, 0x60, 0x12, 0x45, -0x71, 0x12, 0x08, 0x3A, 0x90, 0xA1, 0x68, 0xF1, 0xEF, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, -0x07, 0x90, 0xA1, 0x60, 0x12, 0x45, 0x71, 0x90, 0xA1, 0x64, 0xF1, 0xEF, 0xD0, 0x03, 0xD0, 0x02, -0xD0, 0x01, 0xD0, 0x00, 0x12, 0x45, 0x53, 0x90, 0xA1, 0x6C, 0x12, 0x08, 0x6D, 0x90, 0xA1, 0x6C, -0x12, 0x47, 0xDF, 0x90, 0xA1, 0x5E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x38, 0x45, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0x7F, 0x00, 0x7E, 0x09, 0x71, 0x73, 0x90, 0xA1, 0x60, 0x22, 0x8F, 0x54, 0x7D, -0x17, 0x91, 0x1B, 0x75, 0xF0, 0x0E, 0xE5, 0x54, 0x12, 0xA9, 0x71, 0xE0, 0xFC, 0xF1, 0xB1, 0xFE, -0x54, 0x03, 0xFD, 0xEE, 0x13, 0x13, 0x54, 0x07, 0xFB, 0x90, 0xA0, 0x2C, 0xE0, 0xFE, 0x12, 0xAA, -0x69, 0xAF, 0x04, 0x12, 0xA4, 0x4F, 0xF1, 0xB1, 0x12, 0xA9, 0xBE, 0xFD, 0x51, 0x4E, 0x75, 0xF0, -0x0E, 0xE5, 0x54, 0x31, 0x0C, 0xAD, 0x54, 0xE4, 0xFF, 0x21, 0xA0, 0x7F, 0xFF, 0x31, 0x1D, 0xE4, -0x90, 0xA2, 0x06, 0xF0, 0xA3, 0xF0, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x0F, 0xA3, 0xE0, 0x70, 0x0B, -0xA3, 0xE0, 0x70, 0x07, 0xA3, 0xE0, 0x70, 0x03, 0x7F, 0x01, 0x22, 0xF1, 0xCF, 0x30, 0xE0, 0x15, -0xD3, 0x90, 0xA2, 0x07, 0xE0, 0x94, 0x03, 0x90, 0xA2, 0x06, 0xE0, 0x94, 0x00, 0x40, 0x02, 0x80, -0x13, 0x7F, 0x01, 0x80, 0x1B, 0xD3, 0x90, 0xA2, 0x07, 0xE0, 0x94, 0xE8, 0x90, 0xA2, 0x06, 0xE0, -0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x20, 0xF0, 0x7F, 0x00, 0x22, 0x7F, 0x32, -0x7E, 0x00, 0x12, 0x3E, 0x50, 0x90, 0xA2, 0x06, 0x12, 0x8F, 0x74, 0x80, 0xA9, 0x90, 0x9F, 0xD2, -0xE0, 0x44, 0x02, 0xF0, 0x7D, 0x08, 0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, -0xA1, 0xBE, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x9D, 0x95, 0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D, -0xE0, 0x60, 0x33, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, 0xC2, 0xF0, 0x7D, 0x26, 0x91, 0x1B, 0xEF, -0x64, 0x01, 0x70, 0x07, 0xD1, 0xBA, 0x20, 0xE0, 0x0F, 0x80, 0x0A, 0xF1, 0xCF, 0x30, 0xE0, 0x08, -0xD1, 0xBA, 0x20, 0xE0, 0x03, 0x12, 0xA7, 0xA5, 0x90, 0xA1, 0xC2, 0xE0, 0xFF, 0x7D, 0x27, 0x31, -0x1D, 0x12, 0xA8, 0x17, 0x80, 0x0B, 0x12, 0xA8, 0x17, 0xD1, 0xBA, 0x20, 0xE0, 0x03, 0x12, 0xA7, -0xA5, 0x90, 0x9F, 0xCA, 0xE0, 0x30, 0xE0, 0x0B, 0xF1, 0xCF, 0x30, 0xE0, 0x06, 0xF1, 0xF5, 0x7D, -0x28, 0x31, 0x1D, 0xF1, 0x0A, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA1, 0xB3, 0xA3, -0xE0, 0xFF, 0x7B, 0x08, 0x7D, 0x01, 0xB1, 0x56, 0x90, 0xA1, 0xB6, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, -0xF0, 0xFD, 0x90, 0xA1, 0xB5, 0xE0, 0xFF, 0xF1, 0xA5, 0x54, 0x3F, 0xF0, 0xEF, 0x60, 0x2C, 0xF1, -0xE3, 0x44, 0x10, 0xF0, 0xF1, 0xA5, 0x44, 0x80, 0xF0, 0x12, 0x87, 0xCF, 0x30, 0xE0, 0x26, 0x12, -0x85, 0xC4, 0x50, 0x0E, 0xEF, 0x25, 0xE0, 0x25, 0xE0, 0xFF, 0x74, 0x2B, 0x2D, 0xF1, 0x9D, 0xEF, -0xF0, 0x22, 0x74, 0x2B, 0x2D, 0xF1, 0x9D, 0x74, 0x7F, 0xF0, 0x22, 0xF1, 0xE3, 0x54, 0xEF, 0xF0, -0xF1, 0xA5, 0x44, 0x40, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xF9, -0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0xA1, 0xF8, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0x12, 0xA8, 0xCB, -0x7C, 0x00, 0xAD, 0x07, 0x90, 0xA1, 0xF8, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, 0xA1, 0xF9, 0xE0, -0x60, 0x06, 0x12, 0xA9, 0x9C, 0x44, 0x80, 0xF0, 0xAF, 0x05, 0x74, 0x20, 0x2F, 0xF5, 0x82, 0xE4, -0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0xF0, 0x12, 0xA9, 0x9C, 0x54, 0xC0, 0xF0, 0xAF, 0x05, -0xF1, 0x8F, 0xE0, 0x54, 0x01, 0xFE, 0x90, 0xA1, 0xFA, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xEE, -0x44, 0x02, 0x4B, 0xFE, 0xF1, 0x8F, 0xEE, 0xF0, 0x74, 0x11, 0x2F, 0x12, 0xAA, 0x61, 0x74, 0xFF, -0xF0, 0x74, 0x29, 0x2F, 0xF1, 0xE6, 0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, -0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xE8, 0xEF, 0xF0, 0x90, 0x04, -0x1D, 0xE0, 0x60, 0x20, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, 0xEB, 0xF0, 0x7D, 0x29, 0x91, 0x1B, -0xBF, 0x01, 0x06, 0x12, 0xA8, 0xDF, 0xFF, 0xB1, 0x17, 0x90, 0xA1, 0xEB, 0xE0, 0xFF, 0x7D, 0x2A, -0x31, 0x1D, 0x80, 0x06, 0x12, 0xA8, 0xDF, 0xFF, 0xB1, 0x17, 0xF1, 0x0A, 0xD0, 0xD0, 0x92, 0xAF, -0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xC3, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, -0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1D, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, 0xC7, 0xF0, 0x7D, 0x36, -0x91, 0x1B, 0xBF, 0x01, 0x03, 0x12, 0xA8, 0x82, 0x90, 0xA1, 0xC7, 0xE0, 0xFF, 0x7D, 0x37, 0x31, -0x1D, 0x80, 0x03, 0x12, 0xA8, 0x82, 0xF1, 0xF5, 0x7D, 0x38, 0x31, 0x1D, 0xF1, 0x0A, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0x90, 0xA1, 0x18, 0xEF, 0xF1, 0xBE, 0x90, 0xA0, 0x19, 0x12, 0x66, 0xE8, 0x20, -0xE0, 0x0D, 0x90, 0xA1, 0x19, 0xE0, 0xB4, 0x01, 0x06, 0x7D, 0x36, 0x7F, 0x6F, 0x31, 0x1D, 0x90, -0xA1, 0x18, 0xE0, 0x70, 0x0B, 0x90, 0xA1, 0x1A, 0xE0, 0xFF, 0x7D, 0x05, 0x91, 0x88, 0x80, 0x26, -0x90, 0xA1, 0x18, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0xA1, 0x1A, 0xE0, 0xFF, 0xB1, 0xD2, 0x80, 0x16, -0x90, 0xA1, 0x18, 0xE0, 0xB4, 0x02, 0x0F, 0xA3, 0xE0, 0xB4, 0x01, 0x0A, 0x90, 0xA0, 0x27, 0xE0, -0xFE, 0xA3, 0xE0, 0xFF, 0xD1, 0x11, 0x90, 0xA0, 0x19, 0x12, 0x66, 0xE8, 0x20, 0xE0, 0x0A, 0x90, -0xA1, 0x19, 0xE0, 0x70, 0x04, 0xFD, 0xFF, 0x31, 0x1D, 0x22, 0x90, 0x9D, 0x9B, 0xE0, 0xFF, 0x90, -0xA1, 0xBF, 0xE0, 0xFB, 0x7D, 0x01, 0xB1, 0x56, 0x90, 0xA1, 0xC0, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, -0xF0, 0xFD, 0x90, 0xA1, 0xBE, 0xE0, 0xFF, 0xB1, 0x17, 0x90, 0xA0, 0x2C, 0xE0, 0x22, 0x90, 0xA1, -0x19, 0xEF, 0xF1, 0xBE, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1E, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, -0x1E, 0xF0, 0x7D, 0x01, 0x91, 0x1B, 0xEF, 0x64, 0x01, 0x70, 0x02, 0xF1, 0x11, 0x90, 0xA1, 0x1E, -0xE0, 0xFF, 0x7D, 0x02, 0x31, 0x1D, 0x80, 0x02, 0xF1, 0x11, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, -0x22, 0x90, 0x9D, 0x9D, 0xE0, 0xFF, 0x7B, 0x08, 0x7D, 0x01, 0xB1, 0x56, 0x90, 0xA1, 0x1C, 0xEE, -0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0xA1, 0x19, 0xE0, 0xFF, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, -0x90, 0xA1, 0x23, 0xF0, 0x90, 0xA1, 0x20, 0xEC, 0xF1, 0xBE, 0x90, 0xA1, 0x20, 0xE0, 0xFC, 0xA3, -0xE0, 0xFD, 0xB1, 0x17, 0x90, 0xA1, 0x20, 0xA3, 0xE0, 0xFF, 0xFD, 0x24, 0x0D, 0x12, 0xA9, 0x35, -0x44, 0x80, 0xF0, 0x74, 0x0D, 0x2D, 0x12, 0xA9, 0x35, 0x54, 0xEF, 0xF1, 0x8E, 0xE0, 0x44, 0x02, -0xF1, 0x8E, 0xE0, 0x54, 0x03, 0xF0, 0x90, 0xA1, 0x22, 0xE0, 0xFF, 0x90, 0xA1, 0x20, 0xA3, 0xE0, -0xFE, 0x24, 0x2A, 0x12, 0xA8, 0xC1, 0x90, 0xA1, 0x23, 0xE0, 0xFF, 0xF1, 0x9A, 0xEF, 0xF0, 0x74, -0x2C, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x24, 0x02, 0xF0, 0x22, 0xF0, 0x74, -0x12, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x74, 0x2B, 0x2E, 0xF5, 0x82, 0xE4, -0x34, 0xFC, 0xF5, 0x83, 0x22, 0x74, 0x09, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, -0x22, 0x75, 0xF0, 0x0E, 0xE5, 0x54, 0x90, 0xA0, 0x30, 0x12, 0x45, 0xA9, 0xE0, 0x22, 0xF0, 0xA3, -0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x22, 0x12, 0x08, 0x5A, 0x90, 0xA1, 0x64, 0x02, 0x08, 0x6D, 0x90, -0x9F, 0xCE, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22, 0x7F, 0x84, 0x7E, 0x08, 0x71, 0x73, 0x90, -0xA1, 0x4E, 0x22, 0x74, 0x29, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x12, -0x45, 0x8D, 0x02, 0x45, 0x46, 0x90, 0x05, 0x22, 0xE0, 0x54, 0x6F, 0xFF, 0x22, 0xD3, 0x10, 0xAF, -0x01, 0xC3, 0xC0, 0xD0, 0x12, 0xA3, 0xC9, 0x20, 0xE6, 0x02, 0x01, 0xB5, 0x90, 0x00, 0x8C, 0xE0, -0xF5, 0x6E, 0x7F, 0x8D, 0x12, 0x47, 0xBF, 0x90, 0x00, 0x8E, 0xE0, 0xF5, 0x6F, 0xEF, 0x24, 0xFC, -0x60, 0x0D, 0x24, 0x03, 0x60, 0x02, 0x01, 0xAC, 0xAF, 0x6E, 0x12, 0xA3, 0x73, 0x80, 0x7D, 0x74, -0x92, 0x25, 0x6E, 0x12, 0x75, 0x9B, 0xE0, 0xFB, 0xE4, 0xFD, 0x11, 0xFA, 0xE5, 0x6E, 0x31, 0x07, -0x13, 0x13, 0x11, 0xF5, 0xE5, 0x6E, 0x31, 0x07, 0xD1, 0xCD, 0x11, 0xF7, 0xE5, 0x6E, 0x31, 0x07, -0xC4, 0x11, 0xF5, 0xE5, 0x6E, 0x12, 0x77, 0x94, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x11, 0xFB, 0xE5, -0x6E, 0xD1, 0xC6, 0xE0, 0xFB, 0x0D, 0x91, 0x08, 0xC4, 0x13, 0x54, 0x01, 0xFB, 0x0D, 0x7F, 0x01, -0x91, 0x08, 0x54, 0x1F, 0xFB, 0x0D, 0x11, 0xE6, 0x90, 0x89, 0x00, 0x11, 0xDE, 0x90, 0x89, 0x01, -0x11, 0xEE, 0x11, 0xE6, 0x90, 0x89, 0x02, 0x11, 0xEE, 0x11, 0xE6, 0x90, 0x89, 0x03, 0x11, 0xEE, -0x11, 0xE6, 0x90, 0x89, 0x04, 0x11, 0xDE, 0x90, 0x89, 0x05, 0x11, 0xEE, 0x11, 0xE6, 0x90, 0x89, -0x06, 0x11, 0xEE, 0x11, 0xE6, 0x90, 0x89, 0x07, 0x11, 0xEE, 0x11, 0xBA, 0x12, 0xA3, 0xC9, 0x30, -0xE0, 0x03, 0x12, 0xA3, 0xD0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xEF, 0x70, 0x04, 0x74, 0xF0, 0x80, -0x16, 0xEF, 0xB4, 0x01, 0x04, 0x74, 0xF4, 0x80, 0x0E, 0xEF, 0xB4, 0x02, 0x04, 0x74, 0xF8, 0x80, -0x06, 0xEF, 0xB4, 0x03, 0x08, 0x74, 0xFC, 0x2D, 0x12, 0x9F, 0x40, 0xEB, 0xF0, 0x22, 0x12, 0x45, -0xA9, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x11, 0xBA, 0x75, 0xF0, 0x08, 0xE5, 0x6E, 0x22, 0x12, 0x45, -0xA9, 0xE0, 0xFB, 0x0D, 0x22, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0xFF, 0x11, 0xBA, 0x75, 0xF0, 0x04, -0x22, 0xFF, 0x75, 0xF0, 0x04, 0xE5, 0x51, 0x90, 0x96, 0x15, 0x12, 0x45, 0xA9, 0xE0, 0x22, 0xE4, -0xFF, 0xE4, 0xFE, 0x74, 0x12, 0x2F, 0xD1, 0x2B, 0xE0, 0x54, 0xFE, 0xF0, 0x12, 0xAA, 0x81, 0xBE, -0x03, 0x0D, 0x12, 0x45, 0xA9, 0xE5, 0x82, 0x2E, 0xD1, 0x0E, 0x74, 0x80, 0xF0, 0x80, 0x0A, 0x12, -0x45, 0xA9, 0xE5, 0x82, 0x2E, 0xD1, 0x0E, 0xE4, 0xF0, 0x75, 0xF0, 0x08, 0xEF, 0xD1, 0x1D, 0x2E, -0xD1, 0x0E, 0xE4, 0xF0, 0x0E, 0xBE, 0x10, 0xCB, 0x0F, 0xBF, 0x80, 0xC5, 0xE4, 0x90, 0xAD, 0xE2, -0xF0, 0xFF, 0xE4, 0xFE, 0x75, 0xF0, 0x0A, 0xEF, 0x12, 0x7F, 0xB6, 0x75, 0xF0, 0x02, 0xEE, 0x12, -0xA3, 0x55, 0xF0, 0x0E, 0xBE, 0x05, 0xED, 0x74, 0x12, 0x2F, 0x12, 0x77, 0xA9, 0x74, 0x13, 0xF0, -0x74, 0x92, 0x2F, 0x12, 0x77, 0x64, 0xE4, 0xF0, 0x74, 0x01, 0x2F, 0x12, 0x75, 0xAD, 0x74, 0xC0, -0x12, 0x77, 0xD5, 0xE4, 0xF0, 0xA3, 0xF0, 0x12, 0xA3, 0x5C, 0xE4, 0x12, 0x77, 0x8F, 0x74, 0x13, -0xF0, 0xD1, 0xC2, 0xE4, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x91, 0x0F, 0x54, 0xE0, 0x44, 0x09, 0xF0, -0x75, 0xF0, 0x04, 0xEF, 0x31, 0x07, 0x54, 0xF3, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, 0x07, 0x54, -0xFC, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x91, 0x0F, 0x44, 0x20, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, -0x07, 0x54, 0xCF, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, 0x07, 0x44, 0x40, 0xF0, 0x75, 0xF0, 0x04, -0xEF, 0x31, 0x07, 0x54, 0x7F, 0xF0, 0xD1, 0xC2, 0xE0, 0xFE, 0x12, 0xAA, 0x81, 0x12, 0x45, 0xA9, -0xEE, 0xF0, 0x74, 0x12, 0x2F, 0xD1, 0x2B, 0xE4, 0xF0, 0x0F, 0xEF, 0x64, 0x80, 0x60, 0x02, 0x21, -0x52, 0x74, 0x92, 0x2F, 0x12, 0x8C, 0x4B, 0x74, 0xFF, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x54, 0x7F, -0xF5, 0x51, 0xF1, 0xC5, 0xFF, 0x54, 0x1F, 0xF5, 0x53, 0xEF, 0x54, 0x80, 0xD1, 0xCD, 0xF5, 0x52, -0xD1, 0xBC, 0xFF, 0x54, 0x03, 0xF5, 0x54, 0xEF, 0x54, 0x30, 0xC4, 0x54, 0x0F, 0xF5, 0x57, 0xD1, -0xBC, 0xFF, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03, 0xF5, 0x55, 0xEF, 0x54, 0x80, 0xD1, 0xCD, -0xF5, 0x56, 0xD1, 0xBC, 0xFF, 0x54, 0x08, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xF5, 0x59, 0xEF, 0x54, -0x04, 0x13, 0x13, 0x54, 0x3F, 0xF5, 0x5A, 0xE5, 0x56, 0x12, 0xAA, 0x02, 0x31, 0x01, 0x54, 0x7F, -0x4F, 0xF0, 0xE5, 0x55, 0x12, 0x61, 0xBF, 0x31, 0x01, 0x54, 0xBF, 0x4F, 0xF0, 0xE5, 0x59, 0x60, -0x02, 0x41, 0xE3, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0x75, 0xF0, 0x04, 0xE5, 0x51, 0x91, 0x0F, 0x54, -0xE0, 0x4F, 0xF0, 0xE5, 0x54, 0x54, 0x03, 0x31, 0x01, 0x54, 0xFC, 0x4F, 0xF0, 0xEF, 0x25, 0xE0, -0x25, 0xE0, 0x31, 0x01, 0x54, 0xF3, 0x4F, 0xF0, 0xE5, 0x52, 0x54, 0x01, 0xC4, 0x33, 0x54, 0xE0, -0xFF, 0x75, 0xF0, 0x04, 0xE5, 0x51, 0x91, 0x0F, 0x54, 0xDF, 0x4F, 0xF0, 0xE5, 0x57, 0x54, 0x03, -0xC4, 0x54, 0xF0, 0x31, 0x01, 0x54, 0xCF, 0x4F, 0xD1, 0x26, 0xE0, 0x54, 0xFB, 0xD1, 0x26, 0xE0, -0xFF, 0xE5, 0x5A, 0x25, 0xE0, 0x25, 0xE0, 0xFE, 0xEF, 0x4E, 0xF0, 0xE4, 0xF5, 0x58, 0x85, 0x58, -0x82, 0x75, 0x83, 0x00, 0xA3, 0xA3, 0xA3, 0x12, 0x06, 0xA2, 0xFF, 0x75, 0xF0, 0x08, 0xE5, 0x51, -0xD1, 0x1D, 0x25, 0x58, 0xD1, 0x0E, 0xEF, 0xF0, 0x05, 0x58, 0xE5, 0x58, 0xB4, 0x04, 0xDF, 0xAF, -0x51, 0x91, 0x17, 0x22, 0x90, 0xA0, 0xEA, 0xEF, 0xF0, 0xA3, 0x12, 0x45, 0xBE, 0x90, 0xA0, 0xEA, -0xE0, 0xFF, 0x90, 0x06, 0x34, 0xF0, 0xEF, 0x12, 0x45, 0xC7, 0x53, 0x5B, 0x00, 0x53, 0x60, 0x01, -0x53, 0x65, 0x02, 0x53, 0x6A, 0x10, 0x53, 0x6F, 0x11, 0x53, 0x73, 0x12, 0x53, 0x78, 0x14, 0x53, -0x7D, 0x20, 0x53, 0x82, 0x21, 0x53, 0x86, 0x23, 0x53, 0x8B, 0x24, 0x53, 0x90, 0x25, 0x53, 0x95, -0x27, 0x53, 0x9A, 0x28, 0x53, 0x9F, 0x40, 0x53, 0xA3, 0x42, 0x53, 0xA7, 0x60, 0x53, 0xAC, 0x61, -0x53, 0xB1, 0x62, 0x53, 0xB6, 0x63, 0x53, 0xBB, 0x64, 0x53, 0xC0, 0x65, 0x53, 0xC5, 0x66, 0x53, -0xCA, 0x67, 0x53, 0xCF, 0x68, 0x53, 0xD4, 0x69, 0x53, 0xD9, 0x6B, 0x53, 0xDE, 0x6C, 0x53, 0xE3, -0x6D, 0x53, 0xE8, 0x6E, 0x53, 0xED, 0x6F, 0x00, 0x00, 0x53, 0xF2, 0x91, 0x02, 0x02, 0x98, 0x79, -0x91, 0x02, 0x02, 0x95, 0x9B, 0x91, 0x02, 0x02, 0x98, 0xD8, 0x91, 0x02, 0x02, 0x98, 0xBE, 0x91, -0x02, 0xC1, 0xED, 0x91, 0x02, 0x02, 0x9A, 0xD4, 0x91, 0x02, 0x02, 0x9A, 0xE8, 0x91, 0x02, 0x02, -0x5C, 0xFD, 0x91, 0x02, 0xE1, 0xCB, 0x91, 0x02, 0x02, 0x9A, 0xF7, 0x91, 0x02, 0x02, 0x68, 0x53, -0x91, 0x02, 0x02, 0x97, 0x0F, 0x91, 0x02, 0x02, 0x9A, 0xFF, 0x91, 0x02, 0x02, 0x9B, 0x27, 0x91, -0x02, 0x21, 0xFB, 0x91, 0x02, 0xC1, 0x33, 0x91, 0x02, 0x02, 0x69, 0xE0, 0x91, 0x02, 0x02, 0x8B, -0xB1, 0x91, 0x02, 0x02, 0x87, 0xB4, 0x91, 0x02, 0x02, 0x9B, 0x6F, 0x91, 0x02, 0x02, 0x9B, 0x9C, -0x91, 0x02, 0x02, 0x9B, 0xFA, 0x91, 0x02, 0x02, 0x9C, 0x08, 0x91, 0x02, 0x02, 0x8D, 0x06, 0x91, -0x02, 0x02, 0x9B, 0x83, 0x91, 0x02, 0x02, 0x9C, 0x34, 0x91, 0x02, 0x02, 0x6D, 0x10, 0x91, 0x02, -0x02, 0x9C, 0xD3, 0x91, 0x02, 0x02, 0x8B, 0x49, 0x91, 0x02, 0x02, 0x9C, 0xED, 0x91, 0x02, 0x02, -0x9B, 0x50, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0xA0, 0xEA, 0xE0, 0x90, 0x01, 0xC2, -0xF0, 0x22, 0x90, 0xA0, 0xEB, 0x02, 0x45, 0xB5, 0x11, 0xBA, 0x75, 0xF0, 0x04, 0xE5, 0x6E, 0x90, -0x96, 0x14, 0x12, 0x45, 0xA9, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, -0xDC, 0xEF, 0xF0, 0x75, 0xF0, 0x04, 0x91, 0x0F, 0x54, 0x1F, 0xFB, 0x24, 0xF1, 0x50, 0x02, 0x80, -0x59, 0xE4, 0xF5, 0x6B, 0x90, 0xA1, 0xDC, 0xE0, 0xFD, 0xD1, 0x1A, 0x25, 0x6B, 0xD1, 0x0E, 0xE0, -0xFE, 0xEB, 0x75, 0xF0, 0x07, 0xA4, 0x24, 0x56, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE5, -0x82, 0x25, 0x6B, 0xD1, 0x0E, 0xE4, 0x93, 0xFC, 0xEE, 0x5C, 0x90, 0xA1, 0xDF, 0xF0, 0x75, 0xF0, -0x04, 0xED, 0x31, 0x07, 0x54, 0x03, 0xFF, 0xBF, 0x02, 0x0B, 0xE5, 0x6B, 0x70, 0x07, 0x90, 0xA1, -0xDF, 0xE0, 0x54, 0xF0, 0xF0, 0x90, 0xA1, 0xDF, 0xE0, 0xFF, 0xD1, 0x16, 0x25, 0x6B, 0xD1, 0x0E, -0xEF, 0xF0, 0x05, 0x6B, 0xE5, 0x6B, 0x64, 0x07, 0x70, 0xAA, 0x90, 0xA1, 0xDC, 0xE0, 0x75, 0xF0, -0x04, 0x31, 0x07, 0xFF, 0xC4, 0x54, 0x03, 0xFD, 0xE4, 0x90, 0xA1, 0xDD, 0xF0, 0x75, 0x6C, 0x06, -0xE5, 0x6C, 0xB4, 0x06, 0x07, 0xB1, 0xFD, 0xE0, 0x54, 0x0F, 0x80, 0x07, 0xD1, 0x16, 0x25, 0x6C, -0xD1, 0x0E, 0xE0, 0x90, 0xA1, 0xDE, 0xF0, 0x90, 0xA1, 0xDE, 0xE0, 0x60, 0x33, 0x75, 0x6B, 0x07, -0x12, 0xAA, 0x79, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x12, 0xAA, 0x1D, 0x60, -0x16, 0x12, 0xAA, 0x14, 0x90, 0xA1, 0xDD, 0xF0, 0xED, 0x60, 0x22, 0xE0, 0xD3, 0x94, 0x0B, 0x40, -0x1C, 0xE0, 0x24, 0x20, 0xF0, 0x80, 0x16, 0x15, 0x6B, 0xE5, 0x6B, 0xC3, 0x94, 0x00, 0x50, 0xD0, -0xE5, 0x6C, 0x60, 0x09, 0x15, 0x6C, 0xE5, 0x6C, 0xC3, 0x94, 0x00, 0x50, 0xA3, 0xE4, 0xFC, 0xF5, -0x6C, 0xE5, 0x6C, 0xB4, 0x06, 0x07, 0xB1, 0xFD, 0xE0, 0x54, 0x0F, 0x80, 0x07, 0xD1, 0x16, 0x25, -0x6C, 0xD1, 0x0E, 0xE0, 0x90, 0xA1, 0xDE, 0xF0, 0x90, 0xA1, 0xDE, 0xE0, 0x60, 0x2E, 0xE4, 0xF5, -0x6B, 0x12, 0xAA, 0x79, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x12, 0xAA, 0x1D, -0x60, 0x13, 0x12, 0xAA, 0x14, 0xFC, 0xED, 0x60, 0x1B, 0xEC, 0xD3, 0x94, 0x0B, 0x40, 0x15, 0x74, -0x20, 0x2C, 0xFC, 0x80, 0x0F, 0x05, 0x6B, 0xE5, 0x6B, 0xB4, 0x08, 0xD5, 0x05, 0x6C, 0xE5, 0x6C, -0x64, 0x07, 0x70, 0xAD, 0x90, 0xA1, 0xDD, 0xE0, 0xFF, 0x90, 0xA1, 0xDC, 0xE0, 0xFE, 0x75, 0xF0, -0x04, 0x12, 0x77, 0x94, 0xEF, 0xF0, 0x75, 0xF0, 0x04, 0xEE, 0xD1, 0xC6, 0xEC, 0xF0, 0x75, 0xF0, -0x10, 0xEE, 0x12, 0x7F, 0xBC, 0xFE, 0x54, 0x7F, 0xF5, 0x6D, 0xEE, 0x54, 0x80, 0xFE, 0xE5, 0x6D, -0xD3, 0x9F, 0x40, 0x09, 0x90, 0xA1, 0xDD, 0xE0, 0x4E, 0xF5, 0x6D, 0x80, 0x0C, 0xE5, 0x6D, 0xC3, -0x9C, 0x50, 0x06, 0xAF, 0x06, 0xEC, 0x4F, 0xF5, 0x6D, 0x90, 0xA1, 0xDC, 0xE0, 0xFF, 0x24, 0x12, -0x12, 0x77, 0xA9, 0xE5, 0x6D, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, 0x07, 0x13, 0x13, 0x54, 0x03, -0xF5, 0x6A, 0x90, 0xA1, 0xDC, 0xE0, 0xFF, 0xE4, 0xFB, 0xAD, 0x6D, 0x12, 0x75, 0xDD, 0x90, 0xA1, -0xDC, 0xE0, 0xFF, 0x75, 0xF0, 0x10, 0x90, 0x81, 0x03, 0x12, 0x45, 0xA9, 0xE4, 0xF0, 0x90, 0xA1, -0xDD, 0xE0, 0xFE, 0xC3, 0x94, 0x0C, 0x40, 0x07, 0xD1, 0xD4, 0x74, 0x02, 0xF0, 0x80, 0x19, 0xEE, -0xC3, 0x94, 0x04, 0x90, 0xA1, 0xDC, 0xE0, 0x40, 0x09, 0x24, 0x92, 0xD1, 0xD7, 0x74, 0x01, 0xF0, -0x80, 0x06, 0x24, 0x92, 0xD1, 0xD7, 0xE4, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xFF, 0x90, 0xA1, -0xDC, 0xE0, 0x75, 0xF0, 0x08, 0x90, 0x89, 0x00, 0x12, 0x45, 0xA9, 0xE5, 0x82, 0x2F, 0xF5, 0x82, -0xE4, 0x35, 0x83, 0xF5, 0x83, 0x22, 0x90, 0xA1, 0xDC, 0xE0, 0x75, 0xF0, 0x08, 0x90, 0x89, 0x00, -0x12, 0x45, 0xA9, 0xE5, 0x82, 0x22, 0xF0, 0x74, 0x12, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x99, -0xF5, 0x83, 0x22, 0x12, 0x6F, 0xD2, 0x12, 0x06, 0x89, 0xF5, 0x51, 0x24, 0x12, 0xD1, 0x2B, 0xE0, -0x54, 0x9C, 0xD1, 0x26, 0xC0, 0x83, 0xC0, 0x82, 0xD1, 0xDF, 0x54, 0x01, 0xFE, 0xEF, 0x4E, 0xD0, -0x82, 0xD0, 0x83, 0xD1, 0x26, 0xC0, 0x83, 0xC0, 0x82, 0xD1, 0xDF, 0x54, 0x02, 0xFE, 0xEF, 0x4E, -0xD0, 0x82, 0xD0, 0x83, 0xD1, 0x26, 0xC0, 0x83, 0xC0, 0x82, 0xD1, 0xDF, 0x54, 0x40, 0xFE, 0xEF, -0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xD1, 0x26, 0xC0, 0x83, 0xC0, 0x82, 0xD1, 0xDF, 0x54, 0x20, 0xFE, -0xEF, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0xE5, 0x51, 0xC3, 0x94, 0x80, 0x50, 0x09, 0xD1, 0xBC, -0x12, 0x75, 0x96, 0xEF, 0xF0, 0x80, 0x0B, 0xE5, 0x51, 0xB4, 0x80, 0x06, 0xD1, 0xBC, 0x90, 0x95, -0x91, 0xF0, 0xD1, 0x27, 0xE0, 0x30, 0xE5, 0x11, 0x31, 0x02, 0x13, 0x13, 0x54, 0x03, 0xFB, 0x12, -0x75, 0x97, 0xE0, 0xFD, 0xAF, 0x51, 0x12, 0xA2, 0xAE, 0x22, 0x4F, 0xF0, 0x90, 0x00, 0x02, 0x02, -0x06, 0xA2, 0x75, 0xF0, 0x04, 0xEF, 0x90, 0x96, 0x13, 0x02, 0x45, 0xA9, 0xFF, 0xC4, 0x13, 0x13, -0x13, 0x54, 0x01, 0x22, 0x74, 0x92, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x95, 0xF5, 0x83, 0x22, 0xE0, -0xFF, 0x90, 0xA0, 0xEE, 0x12, 0x45, 0xB5, 0x90, 0x00, 0x03, 0x02, 0x06, 0xA2, 0x12, 0x6F, 0xDF, -0x12, 0x06, 0x89, 0xC4, 0x54, 0x0F, 0xFF, 0xBF, 0x0F, 0x18, 0x90, 0xA0, 0x2C, 0xE0, 0x54, 0xFE, -0xF0, 0x12, 0x6F, 0x6B, 0xF1, 0xBD, 0x12, 0x06, 0x89, 0x54, 0x0F, 0xFF, 0x12, 0x4B, 0xDD, 0x02, -0xA4, 0xCF, 0xF1, 0xBD, 0xF1, 0xC5, 0xFF, 0x12, 0x06, 0x89, 0xFE, 0x54, 0x0F, 0x12, 0xA9, 0x6D, -0xEF, 0xD1, 0xBB, 0x54, 0x03, 0xFF, 0x75, 0xF0, 0x0E, 0xED, 0x12, 0x4F, 0xB6, 0x54, 0xFC, 0xD1, -0xBA, 0x54, 0x1C, 0xFF, 0xEE, 0x54, 0x0F, 0xFE, 0x75, 0xF0, 0x0E, 0x12, 0x4F, 0xB6, 0x54, 0xE3, -0xD1, 0xBA, 0x54, 0xE0, 0xFF, 0x75, 0xF0, 0x0E, 0xEE, 0x12, 0x4F, 0xB6, 0x54, 0x1F, 0x4F, 0x12, -0x6C, 0xDD, 0x12, 0xAA, 0x51, 0xE4, 0xFB, 0xF1, 0xBA, 0x12, 0x5E, 0x3B, 0x12, 0xAA, 0x51, 0x7B, -0x01, 0xF1, 0xBA, 0xD1, 0xE7, 0x12, 0x9B, 0x49, 0x12, 0x06, 0x89, 0xFE, 0x54, 0x0F, 0xFD, 0x75, -0xF0, 0x0E, 0x90, 0xA0, 0x38, 0x12, 0x45, 0xA9, 0xEF, 0xF0, 0xD1, 0xE7, 0xC4, 0x13, 0x54, 0x07, -0xFF, 0x75, 0xF0, 0x0E, 0xED, 0x90, 0xA0, 0x39, 0x12, 0x45, 0xA9, 0xEF, 0xF0, 0xEE, 0xC4, 0x54, -0x0F, 0xFF, 0x14, 0x6D, 0x70, 0x23, 0x90, 0xA0, 0x2D, 0xEF, 0xF0, 0x12, 0x5F, 0xE4, 0x54, 0x0F, -0xC4, 0x54, 0xF0, 0xFF, 0x90, 0xA0, 0x2C, 0xE0, 0x54, 0x0F, 0x4F, 0xF0, 0x54, 0xF1, 0xF0, 0x44, -0x01, 0xF0, 0x7D, 0x20, 0xE4, 0xFF, 0x12, 0x6F, 0x56, 0x22, 0x12, 0xA5, 0x45, 0xAB, 0x51, 0xAA, -0x52, 0xA9, 0x53, 0x22, 0xF0, 0x90, 0x00, 0x01, 0x02, 0x06, 0xA2, 0xD1, 0xBC, 0xFF, 0x30, 0xE0, -0x1D, 0x12, 0x06, 0x89, 0x90, 0x9F, 0xB6, 0xF1, 0xC4, 0x90, 0x9F, 0xB7, 0xF0, 0xEF, 0x54, 0xFE, -0xFF, 0xA3, 0xE0, 0x54, 0x01, 0x4F, 0xF0, 0xD1, 0xE7, 0x90, 0x9F, 0xB9, 0xF0, 0x22, 0x90, 0x9F, -0xB6, 0x74, 0x03, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28, 0xF0, 0xA3, -0x74, 0x05, 0xF0, 0x22, 0x7F, 0xF4, 0x12, 0x47, 0xBF, 0xEF, 0x20, 0xE5, 0x0E, 0x7F, 0xF4, 0x12, -0x47, 0xBF, 0xEF, 0x7F, 0x01, 0x20, 0xE4, 0x05, 0x7F, 0x02, 0x22, 0x7F, 0x03, 0x22, 0x11, 0x04, -0x90, 0x9D, 0x98, 0xEF, 0xF0, 0x11, 0x5C, 0x90, 0x01, 0x64, 0x74, 0x01, 0xF0, 0x90, 0x04, 0x23, -0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x17, 0x12, 0x47, 0xBF, 0xEF, 0x54, 0xFC, 0x44, 0x04, 0xFD, 0x7F, -0x17, 0x12, 0x46, 0xA0, 0x12, 0xA9, 0xF0, 0x44, 0x40, 0xFD, 0x7F, 0x16, 0x12, 0x46, 0xA0, 0x7F, -0x38, 0x12, 0xAA, 0x91, 0x7F, 0x38, 0x12, 0x46, 0xA0, 0x02, 0x37, 0x99, 0x11, 0x8C, 0x11, 0xBA, -0x12, 0x9F, 0x53, 0x12, 0x9F, 0x72, 0xE4, 0xF5, 0x0D, 0xF5, 0x0E, 0xF5, 0x0F, 0x75, 0x10, 0x80, -0xAD, 0x0D, 0x7F, 0x50, 0x12, 0x46, 0xA0, 0xAD, 0x0E, 0x7F, 0x51, 0x12, 0x46, 0xA0, 0xAD, 0x0F, -0x7F, 0x52, 0x12, 0x46, 0xA0, 0xAD, 0x10, 0x7F, 0x53, 0x02, 0x46, 0xA0, 0x90, 0x01, 0x30, 0xE4, -0x11, 0xB2, 0x90, 0x01, 0x38, 0x11, 0xB2, 0xFD, 0x7F, 0x50, 0x12, 0x46, 0xA0, 0xE4, 0xFD, 0x7F, -0x51, 0x12, 0x46, 0xA0, 0xE4, 0xFD, 0x7F, 0x52, 0x12, 0x46, 0xA0, 0xE4, 0xFD, 0x7F, 0x53, 0x02, -0x46, 0xA0, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x01, 0x34, 0x74, 0xFF, 0x11, -0xB2, 0x90, 0x01, 0x3C, 0x11, 0xB2, 0xFD, 0x7F, 0x54, 0x12, 0x46, 0xA0, 0x7D, 0xFF, 0x7F, 0x55, -0x12, 0x46, 0xA0, 0x7D, 0xFF, 0x7F, 0x56, 0x12, 0x46, 0xA0, 0x7D, 0xFF, 0x7F, 0x57, 0x02, 0x46, -0xA0, 0xEF, 0x64, 0x01, 0x70, 0x20, 0x91, 0xB9, 0x90, 0x01, 0x38, 0xE4, 0x11, 0xB2, 0x90, 0x01, -0x30, 0x11, 0xB2, 0x90, 0x01, 0x30, 0x74, 0x10, 0xF0, 0x90, 0x01, 0x39, 0x74, 0x01, 0xF0, 0x90, -0x00, 0x53, 0x74, 0x80, 0xF0, 0x22, 0x12, 0xA7, 0x8C, 0x90, 0x9F, 0xC7, 0xE0, 0x90, 0x01, 0x31, -0xF0, 0x90, 0x9F, 0xC8, 0xE0, 0x90, 0x01, 0x32, 0xF0, 0x90, 0x9F, 0xC9, 0xE0, 0x90, 0x01, 0x33, -0xF0, 0x90, 0x9F, 0xC2, 0xE0, 0x90, 0x01, 0x38, 0xF0, 0x90, 0x9F, 0xC5, 0xE0, 0x90, 0x01, 0x3B, -0xF0, 0xD1, 0xB4, 0x12, 0x87, 0xC1, 0x7F, 0x01, 0x51, 0x8D, 0x7E, 0x00, 0x7F, 0xA3, 0x7D, 0x00, -0x7B, 0x01, 0x7A, 0x9F, 0x79, 0x13, 0x12, 0x08, 0xAA, 0x12, 0xA9, 0x77, 0x12, 0x08, 0xAA, 0x90, -0x9F, 0x16, 0x74, 0x02, 0xF0, 0x90, 0x9F, 0x1D, 0x14, 0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x08, 0x12, -0x95, 0x2F, 0x74, 0x02, 0xF0, 0x12, 0xA9, 0x4F, 0xE4, 0xFD, 0xFF, 0x51, 0x26, 0x7D, 0x0C, 0x7F, -0x02, 0x51, 0x26, 0x51, 0x22, 0x90, 0x9D, 0x98, 0xE0, 0xB4, 0x01, 0x08, 0x90, 0x9F, 0x21, 0x74, -0xDD, 0xF0, 0x80, 0x12, 0x90, 0x9D, 0x98, 0xE0, 0x90, 0x9F, 0x21, 0xB4, 0x03, 0x05, 0x74, 0xD4, -0xF0, 0x80, 0x03, 0x74, 0x40, 0xF0, 0x7F, 0x79, 0x12, 0x47, 0xBF, 0xEF, 0x54, 0x03, 0xFF, 0xBF, -0x02, 0x0F, 0x7F, 0x28, 0x12, 0x47, 0xBF, 0xEF, 0x30, 0xE2, 0x06, 0x90, 0x9F, 0x4E, 0x74, 0x02, -0xF0, 0x12, 0x57, 0xEE, 0x12, 0xA9, 0x4F, 0x90, 0x9F, 0xC1, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x01, -0x38, 0xE0, 0x90, 0x9F, 0xC2, 0xF0, 0x90, 0x01, 0x39, 0xE0, 0x90, 0x9F, 0xC3, 0xF0, 0x90, 0x01, -0x3A, 0xE0, 0x90, 0x9F, 0xC4, 0xF0, 0x90, 0x01, 0x3B, 0xE0, 0x90, 0x9F, 0xC5, 0xF0, 0x90, 0x01, -0x30, 0xE0, 0x90, 0x9F, 0xC6, 0xF0, 0x90, 0x01, 0x31, 0xE0, 0x90, 0x9F, 0xC7, 0xF0, 0x90, 0x01, -0x32, 0xE0, 0x90, 0x9F, 0xC8, 0xF0, 0x90, 0x01, 0x33, 0xE0, 0x90, 0x9F, 0xC9, 0xF0, 0x12, 0x94, -0x9D, 0x7E, 0x00, 0x7F, 0x02, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x9F, 0x79, 0xBA, 0x12, 0x08, 0xAA, -0x12, 0xAA, 0x59, 0x12, 0xAA, 0x49, 0x91, 0x9B, 0xE4, 0x90, 0x9F, 0xBC, 0xF0, 0x22, 0xE0, 0x54, -0x7F, 0xF0, 0x7D, 0x0C, 0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x11, -0xEF, 0xF0, 0x14, 0x60, 0x15, 0x14, 0x60, 0x19, 0x24, 0x02, 0x70, 0x1A, 0xED, 0x54, 0x01, 0xFF, -0x90, 0x9F, 0x13, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x80, 0x0C, 0x90, 0x9F, 0x1A, 0xED, 0xF0, 0x80, -0x05, 0x90, 0x9F, 0x19, 0xED, 0xF0, 0x12, 0xA3, 0xC9, 0x30, 0xE4, 0x2C, 0x90, 0xA2, 0x11, 0xE0, -0x14, 0x60, 0x07, 0x14, 0x60, 0x18, 0x24, 0x02, 0x70, 0x1E, 0x90, 0x9F, 0x13, 0xE0, 0x12, 0xAA, -0x02, 0xFF, 0x90, 0x9F, 0x1A, 0xE0, 0x54, 0x7F, 0x4F, 0xFD, 0x7F, 0x88, 0x80, 0x07, 0x90, 0x9F, -0x19, 0xE0, 0xFD, 0x7F, 0x89, 0x12, 0x46, 0xA0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA2, 0x12, -0xEF, 0xF0, 0xF1, 0x71, 0x90, 0xA2, 0x12, 0xE0, 0x60, 0x02, 0x91, 0x9B, 0x7D, 0x04, 0xF1, 0x53, -0x74, 0x04, 0xF0, 0x22, 0x7D, 0x01, 0x7F, 0x04, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, -0xA2, 0x13, 0xED, 0xF0, 0x90, 0x9F, 0x13, 0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, -0x02, 0x61, 0xEB, 0xEE, 0x12, 0x56, 0xCD, 0x30, 0xE0, 0x02, 0x61, 0xEB, 0x90, 0x9F, 0x1A, 0xE0, -0xFE, 0x6F, 0x70, 0x02, 0x61, 0xEB, 0xEF, 0x70, 0x02, 0x61, 0x65, 0x24, 0xFE, 0x70, 0x02, 0x61, -0x9E, 0x24, 0xFE, 0x60, 0x48, 0x24, 0xFC, 0x70, 0x02, 0x61, 0xD9, 0x24, 0xFC, 0x60, 0x02, 0x61, -0xEB, 0xEE, 0xB4, 0x0E, 0x02, 0x91, 0x22, 0x90, 0x9F, 0x1A, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x51, -0x8D, 0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0x47, 0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x04, -0x0E, 0x90, 0xA2, 0x13, 0xE0, 0xFF, 0x60, 0x05, 0x12, 0x92, 0x23, 0x80, 0x02, 0x91, 0xA1, 0x90, -0x9F, 0x1A, 0xE0, 0x64, 0x08, 0x60, 0x02, 0x61, 0xEB, 0x91, 0xAC, 0x61, 0xEB, 0x90, 0x9F, 0x1A, -0xE0, 0x70, 0x04, 0x7F, 0x01, 0x51, 0x8D, 0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0x47, -0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0xF0, 0xBF, 0x01, 0x02, 0x91, 0x22, 0x90, 0x9F, -0x1A, 0xE0, 0x64, 0x0C, 0x60, 0x02, 0x61, 0xEB, 0x71, 0xF0, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x61, -0xEB, 0x91, 0x6D, 0x61, 0xEB, 0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0xF0, 0xBF, 0x01, -0x02, 0x91, 0x22, 0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0x47, 0x90, 0x9F, 0x1A, 0xE0, -0xB4, 0x0C, 0x07, 0x71, 0xF0, 0xBF, 0x01, 0x02, 0x91, 0x6D, 0x90, 0x9F, 0x1A, 0xE0, 0x64, 0x04, -0x70, 0x59, 0x12, 0xA6, 0xF3, 0xEF, 0x64, 0x01, 0x70, 0x51, 0x91, 0xB9, 0x80, 0x4D, 0x90, 0x9F, -0x1A, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0xF0, 0xBF, 0x01, 0x02, 0x91, 0x22, 0x90, 0x9F, 0x1A, 0xE0, -0xB4, 0x06, 0x02, 0x91, 0x47, 0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x0C, 0x07, 0x71, 0xF0, 0xBF, 0x01, -0x02, 0x91, 0x6D, 0x90, 0x9F, 0x1A, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x51, 0x8D, 0x90, 0x9F, 0x1A, -0xE0, 0xB4, 0x04, 0x17, 0x12, 0x9A, 0xBD, 0x80, 0x12, 0x90, 0x9F, 0x1A, 0xE0, 0xB4, 0x0C, 0x0B, -0x90, 0x9F, 0x14, 0x12, 0x6E, 0xBB, 0x30, 0xE0, 0x02, 0xF1, 0x1C, 0xD0, 0xD0, 0x92, 0xAF, 0x22, -0x90, 0x9F, 0xCA, 0xE0, 0x30, 0xE0, 0x0D, 0x90, 0x9F, 0xD1, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, -0xE0, 0x08, 0x80, 0x1B, 0x12, 0x6F, 0x9C, 0xBF, 0x01, 0x15, 0x90, 0x9F, 0x13, 0x12, 0x66, 0xE8, -0x20, 0xE0, 0x0C, 0x90, 0x9F, 0x19, 0xE0, 0xD3, 0x94, 0x04, 0x50, 0x03, 0x7F, 0x01, 0x22, 0x7F, -0x00, 0x22, 0x90, 0x9F, 0x14, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04, 0x51, 0x22, 0x80, 0x12, 0x12, -0xA8, 0x77, 0xF1, 0xEA, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x9F, 0x12, 0x74, 0x04, -0xF0, 0xE4, 0xFD, 0xFF, 0x02, 0x49, 0x1D, 0x90, 0x9F, 0x14, 0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, -0x07, 0xE0, 0x44, 0x40, 0xF1, 0xEA, 0x80, 0x0F, 0x51, 0x1E, 0x90, 0x05, 0x27, 0xE0, 0x54, 0x7F, -0xF0, 0x90, 0x9F, 0x12, 0x74, 0x0C, 0xF0, 0xE4, 0xFD, 0xFF, 0x02, 0x49, 0x1D, 0x12, 0x91, 0x23, -0x70, 0x22, 0x90, 0x9F, 0x14, 0xE0, 0x54, 0xFD, 0xF0, 0x7D, 0x2C, 0x7F, 0x6F, 0x12, 0x49, 0x1D, -0x12, 0x4C, 0x7D, 0xBF, 0x01, 0x0E, 0x90, 0x9F, 0x13, 0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E, 0xF1, -0x53, 0x74, 0x0E, 0xF0, 0x22, 0xE4, 0xFD, 0x7F, 0x0C, 0x51, 0xA8, 0xE4, 0xFD, 0xFF, 0x02, 0x49, -0x1D, 0x12, 0xAA, 0x59, 0x91, 0x9B, 0x7D, 0x0C, 0x7F, 0x01, 0x41, 0x26, 0xF1, 0x71, 0x91, 0x9B, -0x51, 0x22, 0x90, 0x9F, 0x12, 0x74, 0x0C, 0xF0, 0x22, 0x7D, 0x2D, 0x12, 0x4C, 0x1B, 0x90, 0x01, -0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, 0x03, 0xD1, 0xB8, 0x12, 0x62, 0x52, 0xE4, 0xFD, 0x7F, 0x01, -0x51, 0x26, 0xE4, 0x90, 0x9F, 0x12, 0xF0, 0x22, 0x90, 0x9F, 0xCA, 0xE0, 0x20, 0xE0, 0x1D, 0x90, -0x9F, 0x17, 0xE0, 0x64, 0x01, 0x70, 0x15, 0x12, 0x8F, 0xEE, 0x12, 0x6F, 0x95, 0x60, 0x05, 0x91, -0x95, 0x02, 0x93, 0x8A, 0x90, 0x9F, 0x1A, 0xE0, 0x70, 0x02, 0x51, 0xA4, 0x22, 0x12, 0x6F, 0xD2, -0x12, 0x06, 0x89, 0xFF, 0x54, 0x7F, 0x90, 0x9F, 0x17, 0xF0, 0xEF, 0x12, 0x56, 0xCD, 0xA3, 0x12, -0x57, 0xC4, 0xFF, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFE, 0x90, 0x9F, 0x15, 0xE0, 0x54, 0xF0, 0x4E, -0xF0, 0x12, 0x56, 0xE7, 0x54, 0x01, 0x25, 0xE0, 0xFE, 0x90, 0x9F, 0x13, 0xE0, 0x54, 0xFD, 0x4E, -0xF0, 0xEF, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x12, 0x6F, 0x95, 0x12, 0x56, 0xBA, 0x90, 0x9F, -0x16, 0xF0, 0xF1, 0xE4, 0x30, 0xE0, 0x52, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0xC3, 0x94, 0x04, 0x90, -0x9F, 0x29, 0x50, 0x04, 0xEF, 0xF0, 0x80, 0x2A, 0x74, 0x03, 0xF0, 0xD1, 0x32, 0xE9, 0x24, 0x06, -0xF9, 0xE4, 0x3A, 0xFA, 0x12, 0x06, 0x89, 0xFF, 0x74, 0x03, 0x24, 0xFD, 0xFE, 0xEF, 0xC4, 0x54, -0x0F, 0xFD, 0xEF, 0x54, 0x0F, 0xFF, 0xED, 0x2E, 0x54, 0x0F, 0xFE, 0xC4, 0x54, 0xF0, 0x4F, 0x12, -0x06, 0xCF, 0xD1, 0x32, 0xF1, 0xE4, 0xC4, 0x54, 0x0F, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x9F, 0x1F, -0x50, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x02, 0xEF, 0xF0, 0xD1, 0x32, 0x12, 0x6C, 0xDE, 0xFD, 0x7F, -0x02, 0x51, 0x26, 0xD1, 0x32, 0xD1, 0x3B, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x9F, 0xBB, 0x12, 0x6D, -0x01, 0xD1, 0x39, 0x12, 0x6C, 0xF7, 0x90, 0x9F, 0xBB, 0x12, 0x6F, 0x03, 0xD1, 0x38, 0x12, 0x6F, -0x27, 0x90, 0x9F, 0xBB, 0x12, 0x6F, 0x0C, 0xD1, 0x38, 0x12, 0x6D, 0xE5, 0x4E, 0x90, 0x9F, 0xBB, -0xF0, 0x12, 0x69, 0xCD, 0x20, 0xE0, 0x29, 0xEF, 0xC3, 0x13, 0x20, 0xE0, 0x0B, 0x75, 0x52, 0x01, -0x90, 0xA0, 0x0C, 0xE0, 0x60, 0x0B, 0x80, 0x0E, 0xE4, 0xF5, 0x52, 0x90, 0xA0, 0x0C, 0xE0, 0x60, -0x05, 0xE4, 0xF5, 0x51, 0x80, 0x03, 0x75, 0x51, 0x01, 0xAD, 0x52, 0xAF, 0x51, 0x12, 0x62, 0xCD, -0xD1, 0x32, 0x90, 0xA0, 0xF1, 0x12, 0x45, 0xBE, 0x12, 0xA6, 0xA2, 0x90, 0x9F, 0x17, 0xE0, 0xFF, -0xD1, 0x41, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x13, 0x90, 0xA0, 0xF1, 0x12, 0x45, 0xB5, 0x12, 0x57, -0xC5, 0x54, 0x0F, 0xFF, 0x12, 0x56, 0xBC, 0xFD, 0x12, 0xA6, 0xC3, 0x22, 0x90, 0xA0, 0xEE, 0x12, -0x45, 0xBE, 0x90, 0xA0, 0xEE, 0x02, 0x45, 0xB5, 0x4E, 0xFF, 0xF0, 0x90, 0x00, 0x05, 0x02, 0x06, -0xA2, 0xEF, 0x70, 0x31, 0x7D, 0x78, 0x7F, 0x02, 0xF1, 0x65, 0x7D, 0x02, 0x7F, 0x03, 0xF1, 0x65, -0x7D, 0xC8, 0x7F, 0x02, 0x12, 0x6F, 0x6F, 0x12, 0x91, 0xD0, 0x90, 0x9E, 0x8D, 0xE0, 0x70, 0x0A, -0xD1, 0xC5, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x80, 0x06, 0x7D, 0x01, 0x7F, 0x0C, 0x51, 0xA8, -0xD1, 0xC9, 0x02, 0xAA, 0x49, 0x90, 0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x7D, -0x78, 0xFF, 0xD1, 0xB8, 0x7D, 0x02, 0x7F, 0x03, 0xD1, 0xB8, 0x90, 0x06, 0x0A, 0xE0, 0x44, 0x07, -0x12, 0x95, 0x37, 0x90, 0x9E, 0x8D, 0xE0, 0xB4, 0x01, 0x10, 0x12, 0x97, 0x49, 0x90, 0x9F, 0x1A, -0xE0, 0x20, 0xE2, 0x09, 0x7D, 0x01, 0x7F, 0x04, 0x41, 0xA8, 0x12, 0x91, 0xB6, 0x22, 0x7D, 0x02, -0x7F, 0x02, 0xD1, 0xB8, 0x7D, 0x01, 0x7F, 0x02, 0x74, 0x15, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, -0x74, 0x30, 0x02, 0x6F, 0x60, 0xF1, 0x71, 0x91, 0xA1, 0x90, 0x9F, 0x13, 0xE0, 0x54, 0xF7, 0xF0, -0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07, 0xEF, 0x54, 0x01, 0xFE, 0x90, 0x9F, -0xBD, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0xEF, 0x64, 0x01, 0x70, 0x22, 0x90, 0x01, 0x53, 0xF0, 0x90, -0x9F, 0xBF, 0xE0, 0x60, 0x0C, 0x7D, 0x10, 0x7F, 0x03, 0x12, 0x6F, 0x56, 0x12, 0x97, 0x51, 0x80, -0x16, 0x12, 0xA9, 0xC8, 0x12, 0x6F, 0x6F, 0xF1, 0x5B, 0xF1, 0x1C, 0x80, 0x0A, 0x12, 0xA9, 0xC8, -0x12, 0x6F, 0x56, 0xD1, 0xAE, 0x91, 0xAC, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7D, 0x2F, 0x12, 0x62, -0x4D, 0x7D, 0x08, 0xF1, 0x53, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x9F, 0xBD, 0xE0, 0x30, 0xE0, 0x22, -0x12, 0x97, 0x51, 0x90, 0x9F, 0xC0, 0xE0, 0x60, 0x04, 0x14, 0xF0, 0x80, 0xDF, 0x90, 0x9F, 0xBE, -0xE0, 0x14, 0x90, 0x9F, 0xC0, 0xF0, 0x90, 0x05, 0x73, 0x74, 0x01, 0xF0, 0xE4, 0xFF, 0xD1, 0xD1, -0xD1, 0xAE, 0x22, 0x7F, 0x01, 0x51, 0x26, 0x90, 0x9F, 0x12, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0xF1, -0x65, 0x7D, 0x01, 0x7F, 0x02, 0x74, 0x15, 0x12, 0xAA, 0x89, 0xFE, 0xF6, 0x74, 0x30, 0x02, 0x6F, -0x60, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90, -0x01, 0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, 0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, -0x12, 0x66, 0xE4, 0x30, 0xE0, 0x05, 0x7F, 0x03, 0x12, 0x62, 0x14, 0x90, 0x9F, 0xE6, 0xE0, 0x20, -0xE0, 0x32, 0x12, 0x97, 0x07, 0x30, 0xE0, 0x2C, 0x90, 0xA0, 0x0C, 0xE0, 0x60, 0x07, 0xE4, 0x90, -0xA2, 0x02, 0xF0, 0x80, 0x06, 0x90, 0xA2, 0x02, 0x74, 0x01, 0xF0, 0xEF, 0xC4, 0x13, 0x54, 0x07, -0x90, 0xA2, 0x03, 0x30, 0xE0, 0x05, 0x74, 0x01, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0x90, 0xA2, -0x02, 0x12, 0x62, 0xC8, 0x12, 0x63, 0xED, 0x44, 0x01, 0xFD, 0x7F, 0x02, 0x12, 0x46, 0xA0, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0x06, 0x02, 0x06, 0xA2, 0xF0, 0x7D, 0x04, 0x7F, 0x01, 0x41, -0x26, 0x75, 0xE8, 0x07, 0x75, 0xA8, 0x85, 0x22, 0x7F, 0x81, 0x12, 0x47, 0xBF, 0xEF, 0x54, 0xFE, -0xFD, 0x7F, 0x81, 0x12, 0x46, 0xA0, 0x7F, 0x80, 0x12, 0x47, 0xFA, 0xFD, 0x7F, 0x80, 0x12, 0x46, -0xA0, 0x12, 0x9F, 0x97, 0x12, 0x3E, 0x11, 0x31, 0xCD, 0x12, 0xA0, 0x38, 0x7F, 0x01, 0x12, 0x43, -0xA5, 0x90, 0xA0, 0x2B, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x43, 0xA5, 0x90, 0xA0, 0x2B, 0xE0, 0x04, -0xF0, 0x12, 0x58, 0x1E, 0x11, 0x90, 0x7F, 0x80, 0x12, 0xAA, 0x91, 0x7F, 0x80, 0x12, 0x46, 0xA0, -0x75, 0x28, 0xFF, 0x12, 0x5F, 0xF1, 0x12, 0x9F, 0xBD, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0xDD, 0x51, -0x0D, 0xEF, 0x64, 0x01, 0x70, 0x22, 0x90, 0xA0, 0xDD, 0xE0, 0x54, 0x07, 0xF0, 0xE0, 0xFF, 0x64, -0x07, 0x60, 0x04, 0xEF, 0xB4, 0x04, 0x11, 0x12, 0x9F, 0x48, 0xBF, 0x01, 0x0B, 0x12, 0xA9, 0xF0, -0x44, 0x60, 0xFD, 0x7F, 0x16, 0x12, 0x46, 0xA0, 0x7F, 0x81, 0x12, 0x47, 0xBF, 0xEF, 0x44, 0x04, -0xFD, 0x7F, 0x81, 0x12, 0x46, 0xA0, 0x12, 0xA0, 0x42, 0x31, 0xEB, 0xE4, 0xFF, 0x02, 0x44, 0x2E, -0x12, 0xA6, 0x7D, 0x12, 0x9D, 0x83, 0x12, 0x51, 0x0F, 0x12, 0xA6, 0x83, 0x12, 0x59, 0x3A, 0x31, -0xC7, 0x12, 0xA4, 0xCF, 0x7E, 0x00, 0x7F, 0x19, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x9F, 0x79, 0xFD, -0x12, 0x08, 0xAA, 0x12, 0x9B, 0xED, 0x90, 0xA0, 0x04, 0x12, 0x45, 0x71, 0x90, 0xA0, 0x00, 0x12, -0x08, 0x6D, 0x90, 0x9D, 0x98, 0xE0, 0xFF, 0x64, 0x02, 0x70, 0x22, 0x31, 0xB8, 0x30, 0xE0, 0x02, -0x7E, 0x01, 0x90, 0xA0, 0x0C, 0xEE, 0xF0, 0x31, 0xB8, 0x30, 0xE1, 0x02, 0x7E, 0x01, 0x90, 0xA0, -0x0D, 0xEE, 0xF0, 0x90, 0xFD, 0x80, 0xE0, 0x90, 0x02, 0xFB, 0xF0, 0x80, 0x3A, 0xEF, 0x64, 0x01, -0x70, 0x15, 0x31, 0x51, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0xA0, 0x0C, 0xEF, 0xF0, 0x31, 0x51, -0x30, 0xE1, 0x02, 0x7F, 0x01, 0x80, 0x1B, 0x90, 0x9D, 0x98, 0xE0, 0x64, 0x03, 0x70, 0x18, 0x31, -0x4A, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0xA0, 0x0C, 0xEF, 0xF0, 0x31, 0x4A, 0x30, 0xE1, 0x02, -0x7F, 0x01, 0x90, 0xA0, 0x0D, 0xEF, 0xF0, 0x90, 0xFD, 0x68, 0xE0, 0x44, 0x02, 0xF0, 0x7F, 0x01, -0x51, 0x14, 0x31, 0x58, 0x12, 0x98, 0x24, 0x90, 0x9F, 0xE4, 0x74, 0x01, 0xF0, 0x90, 0xA0, 0x19, -0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x04, 0x8F, 0xE4, 0xF0, 0x22, 0x90, 0xFD, 0x78, 0xE0, 0x7F, 0x00, -0x22, 0x90, 0xFD, 0x70, 0xE0, 0x7F, 0x00, 0x22, 0x7E, 0x00, 0x7F, 0x33, 0x7D, 0x00, 0x7B, 0x01, -0x7A, 0x9F, 0x79, 0xCA, 0x12, 0x08, 0xAA, 0x90, 0x9F, 0xCB, 0x74, 0x0B, 0xF0, 0xA3, 0x74, 0x08, -0xF0, 0x90, 0x9D, 0x98, 0xE0, 0xFC, 0x64, 0x02, 0x70, 0x14, 0x31, 0xB8, 0x30, 0xE2, 0x02, 0x7E, -0x01, 0xEE, 0x31, 0xBF, 0xFE, 0x90, 0x9F, 0xCD, 0xE0, 0x54, 0xBF, 0x4E, 0xF0, 0x22, 0xEC, 0x64, -0x01, 0x70, 0x09, 0x31, 0x51, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0x80, 0x0F, 0x90, 0x9D, 0x98, 0xE0, -0x64, 0x03, 0x70, 0x13, 0x31, 0x4A, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0xEF, 0x31, 0xBF, 0xFF, 0x90, -0x9F, 0xCD, 0xE0, 0x54, 0xBF, 0x4F, 0xF0, 0x22, 0x90, 0xFD, 0x80, 0xE0, 0x7E, 0x00, 0x22, 0x54, -0x01, 0xC4, 0x33, 0x33, 0x54, 0xC0, 0x22, 0x12, 0xA9, 0x77, 0x02, 0x08, 0xAA, 0x90, 0x01, 0x01, -0xE0, 0x44, 0x04, 0xF0, 0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x12, 0x8F, 0x90, 0x90, 0x01, 0x99, -0xE0, 0x44, 0xC0, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x80, 0xF0, 0x22, 0x7B, 0x01, 0x7A, 0xA0, 0x79, -0xDE, 0x51, 0x0D, 0xBF, 0x01, 0x16, 0x90, 0xA0, 0xDE, 0xE0, 0x54, 0x30, 0xFF, 0xBF, 0x20, 0x07, -0x90, 0xA0, 0x59, 0x74, 0x01, 0xF0, 0x22, 0xE4, 0x90, 0xA0, 0x59, 0xF0, 0x22, 0x7F, 0xFB, 0x7E, -0x01, 0x02, 0x34, 0xC1, 0x90, 0x9F, 0xF0, 0xD1, 0xE8, 0x30, 0xE0, 0x07, 0x90, 0x07, 0x78, 0x74, -0x09, 0xF0, 0x22, 0x90, 0x9F, 0xCF, 0xE0, 0x30, 0xE0, 0x1D, 0xEF, 0x24, 0xFD, 0x60, 0x0E, 0x24, -0xFA, 0x60, 0x0E, 0x24, 0xFC, 0x60, 0x0E, 0x24, 0x0C, 0x7F, 0x02, 0x80, 0x0A, 0x7F, 0x03, 0x80, -0x06, 0x7F, 0x0B, 0x80, 0x02, 0x7F, 0x0E, 0x90, 0x07, 0x78, 0xEF, 0xF0, 0x22, 0x7F, 0xFF, 0x12, -0x49, 0x1D, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x4C, 0x1F, 0x71, 0xED, 0x71, 0xD7, -0x71, 0xD7, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x12, 0x46, 0xA0, 0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0, -0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x20, 0xD1, 0xE4, 0x30, 0xE0, 0x04, -0x7F, 0x01, 0x51, 0x14, 0x12, 0x97, 0x07, 0x30, 0xE0, 0x31, 0x90, 0xA0, 0x0C, 0xE0, 0x60, 0x08, -0x90, 0xA2, 0x04, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0xA2, 0x04, 0xF0, 0xEF, 0xC4, 0x13, -0x54, 0x07, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA2, 0x05, 0xF0, 0x80, 0x06, 0x90, 0xA2, 0x05, 0x74, -0x02, 0xF0, 0x90, 0xA2, 0x04, 0x51, 0xC8, 0x7F, 0x01, 0x51, 0x14, 0x90, 0x9F, 0xBA, 0xE0, 0x60, -0x02, 0xE4, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xD3, 0x10, 0xAF, -0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x26, 0x8D, 0x27, 0x90, 0x9F, 0xCD, 0x12, 0x4F, 0xD2, 0x30, 0xE0, -0x02, 0x61, 0xBE, 0x90, 0xA0, 0x0D, 0xE0, 0x70, 0x59, 0xE5, 0x26, 0x64, 0x02, 0x60, 0x26, 0xE5, -0x27, 0x70, 0x22, 0x71, 0xC3, 0xE5, 0x26, 0x90, 0xA1, 0x9D, 0xB4, 0x01, 0x05, 0x12, 0x45, 0x71, -0x80, 0x07, 0xD1, 0xC9, 0xEE, 0x44, 0x02, 0xFE, 0xEC, 0x71, 0xD1, 0x12, 0x47, 0xDC, 0x7F, 0x48, -0x7E, 0x09, 0x12, 0x38, 0x45, 0xE5, 0x27, 0x64, 0x02, 0x70, 0x02, 0x61, 0xBE, 0xE5, 0x27, 0x70, -0x02, 0x61, 0xBE, 0x71, 0xC3, 0x90, 0xA0, 0x0C, 0xE0, 0x90, 0xA1, 0x9D, 0x60, 0x04, 0xD1, 0xC9, -0x80, 0x07, 0x12, 0x45, 0x71, 0xEE, 0x44, 0x02, 0xFE, 0x71, 0xD0, 0x12, 0x47, 0xDC, 0x7F, 0x48, -0x80, 0x77, 0xE5, 0x26, 0x64, 0x02, 0x60, 0x25, 0xB1, 0x50, 0x54, 0xFC, 0xFF, 0x71, 0xD0, 0xE5, -0x26, 0x90, 0xA1, 0x9D, 0xB4, 0x01, 0x08, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x01, 0x80, 0x06, 0x12, -0x45, 0x71, 0xEF, 0x44, 0x02, 0xFF, 0x71, 0xD0, 0x12, 0x47, 0xDC, 0xD1, 0xAA, 0xE5, 0x27, 0x64, -0x02, 0x60, 0x4B, 0x12, 0xA9, 0xF9, 0xFF, 0x71, 0xD0, 0xE5, 0x27, 0x70, 0x09, 0xD1, 0xC1, 0x44, -0x77, 0xFF, 0x71, 0xD0, 0x80, 0x2E, 0xD1, 0xC1, 0x44, 0x66, 0xFF, 0x71, 0xD0, 0xB1, 0x50, 0x54, -0xFC, 0xD1, 0xB1, 0x90, 0xA0, 0x0C, 0xE0, 0x90, 0xA1, 0xA1, 0x60, 0x08, 0x12, 0x45, 0x71, 0xEF, -0x44, 0x02, 0x80, 0x06, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x01, 0xD1, 0xB1, 0x90, 0xA1, 0xA1, 0x12, -0x47, 0xDF, 0xD1, 0xAA, 0x12, 0x47, 0xDC, 0x7F, 0x30, 0x7E, 0x09, 0x12, 0x38, 0x45, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0xEE, 0x54, 0xF0, 0xFE, -0xEC, 0x90, 0xA1, 0x9D, 0x02, 0x08, 0x6D, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x12, 0x46, 0xA0, 0x7F, -0x02, 0x12, 0x47, 0xBF, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x02, 0x12, 0x46, 0xA0, 0x7F, 0x02, 0x12, -0x47, 0xBF, 0xEF, 0x22, 0xAD, 0x07, 0xED, 0x70, 0x19, 0xD1, 0xB9, 0x70, 0x02, 0x80, 0x17, 0xBC, -0x01, 0x02, 0x80, 0x19, 0xD1, 0xB9, 0xBC, 0x02, 0x02, 0x80, 0x1B, 0xEC, 0x64, 0x03, 0x70, 0x21, -0x80, 0x1B, 0xD1, 0xD1, 0x70, 0x04, 0x7F, 0x01, 0x80, 0x15, 0xBC, 0x01, 0x04, 0x7F, 0x03, 0x80, -0x0E, 0xD1, 0xD1, 0xBC, 0x02, 0x04, 0x7F, 0x09, 0x80, 0x05, 0xBC, 0x03, 0x04, 0x7F, 0x0D, 0x51, -0x14, 0x90, 0xA0, 0x19, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x41, 0xED, 0x70, 0x1F, 0xA3, -0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA1, 0x18, 0xF0, 0x80, 0x06, 0x90, -0xA1, 0x18, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0x18, 0xE0, 0xFD, 0xE4, 0xFF, 0x80, 0x1D, 0x90, 0xA0, -0x1A, 0x12, 0x4F, 0xD2, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA1, 0x18, 0xF0, 0x80, 0x06, 0x90, 0xA1, -0x18, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0x18, 0xE0, 0xFD, 0x7F, 0x01, 0x51, 0xCD, 0x22, 0x90, 0xA1, -0x29, 0xEF, 0xF0, 0x90, 0xA0, 0x0D, 0xE0, 0x70, 0x4D, 0x12, 0x8A, 0x2E, 0xEE, 0x54, 0x0F, 0xFE, -0xE4, 0xFD, 0xFC, 0x90, 0xA1, 0x2A, 0x12, 0x08, 0x6D, 0xE4, 0x7F, 0x80, 0xB1, 0x42, 0x70, 0x05, -0x90, 0x9F, 0xEC, 0x80, 0x1B, 0xE4, 0xFF, 0xFE, 0xB1, 0x44, 0x70, 0x0A, 0x90, 0x9F, 0xEC, 0x04, -0xF0, 0xE4, 0xA3, 0xF0, 0x80, 0x4C, 0xE4, 0xFF, 0xB1, 0x42, 0x70, 0x09, 0x90, 0x9F, 0xEC, 0x04, -0xF0, 0xA3, 0xF0, 0x80, 0x3D, 0xE4, 0x7F, 0x80, 0xFE, 0xB1, 0x44, 0x70, 0x35, 0x90, 0x9F, 0xEC, -0xF0, 0xA3, 0x04, 0xF0, 0x80, 0x2C, 0xB1, 0x50, 0x54, 0x02, 0xD1, 0xFE, 0x60, 0x08, 0x90, 0x9F, -0xEC, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x9F, 0xEC, 0xF0, 0x7F, 0x30, 0xB1, 0x52, 0x54, -0x01, 0xD1, 0xFE, 0x60, 0x07, 0xE4, 0x90, 0x9F, 0xED, 0xF0, 0x80, 0x06, 0x90, 0x9F, 0xED, 0x74, -0x01, 0xF0, 0x90, 0x9F, 0xE6, 0xE0, 0x44, 0x01, 0xF0, 0x7D, 0x11, 0x51, 0x4D, 0x90, 0x07, 0x78, -0xE0, 0x90, 0x9F, 0xEB, 0xF0, 0xF1, 0xBF, 0x51, 0xCD, 0x90, 0xA1, 0x29, 0xE0, 0xFD, 0x70, 0x02, -0x80, 0x1C, 0xED, 0xB4, 0x01, 0x06, 0xB1, 0x59, 0x44, 0x20, 0xF0, 0x22, 0x90, 0xA1, 0x29, 0xE0, -0xFD, 0xB4, 0x02, 0x06, 0xB1, 0x59, 0x44, 0x60, 0xF0, 0x22, 0xED, 0xB4, 0x03, 0x03, 0xB1, 0x59, -0xF0, 0x22, 0x7E, 0x02, 0xFD, 0xFC, 0x90, 0xA1, 0x2A, 0x12, 0x45, 0x8D, 0xC3, 0x02, 0x45, 0x60, -0x7F, 0x2C, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0xEF, 0x22, 0x90, 0x9F, 0xE6, 0xE0, 0x54, 0x1F, 0x22, -0x90, 0xA1, 0x18, 0xEF, 0xF0, 0x90, 0xA1, 0x1A, 0x74, 0x02, 0xF0, 0x7F, 0x01, 0x12, 0x97, 0xD0, -0x90, 0x9F, 0xCE, 0x12, 0x6E, 0xBB, 0x30, 0xE0, 0x21, 0x90, 0xA1, 0x18, 0xE0, 0xB4, 0x02, 0x04, -0x7D, 0x07, 0x80, 0x09, 0x90, 0xA1, 0x18, 0xE0, 0xB4, 0x05, 0x07, 0x7D, 0x0D, 0x7F, 0xFF, 0x12, -0x49, 0x1D, 0x12, 0x4C, 0x1F, 0xBF, 0x01, 0x02, 0x51, 0x52, 0x90, 0x9F, 0xCE, 0xE0, 0x12, 0x56, -0xCD, 0x30, 0xE0, 0x04, 0x7F, 0x03, 0x80, 0x02, 0x7F, 0x01, 0x51, 0x14, 0x90, 0xA1, 0x18, 0xE0, -0xB4, 0x02, 0x0D, 0x90, 0x9F, 0xCB, 0xE0, 0x24, 0x03, 0xFF, 0x90, 0x9F, 0xDB, 0x12, 0x82, 0x98, -0x90, 0x9F, 0xCA, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA1, 0x19, 0xF0, 0x80, 0x06, -0x90, 0xA1, 0x19, 0x74, 0x01, 0xF0, 0x12, 0xAA, 0x38, 0x20, 0xE0, 0x13, 0x90, 0xA0, 0x0C, 0xE0, -0x60, 0x08, 0x90, 0xA1, 0x1A, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0xA1, 0x1A, 0xF0, 0x90, -0xA1, 0x1A, 0xE0, 0xFF, 0x90, 0xA1, 0x19, 0xE0, 0xFD, 0x51, 0xCD, 0xE4, 0x90, 0x9F, 0xDD, 0xF0, -0x90, 0xA1, 0x18, 0xE0, 0xFF, 0xB4, 0x02, 0x05, 0x12, 0x82, 0xB2, 0x80, 0x09, 0xEF, 0xB4, 0x05, -0x05, 0xE4, 0x90, 0x9F, 0xDE, 0xF0, 0x12, 0x86, 0x1B, 0x30, 0xE0, 0x17, 0x90, 0xA1, 0x18, 0xE0, -0xB4, 0x02, 0x04, 0x7D, 0x08, 0x80, 0x4D, 0x90, 0xA1, 0x18, 0xE0, 0x64, 0x05, 0x70, 0x4A, 0x7D, -0x0E, 0x80, 0x41, 0x12, 0x86, 0x13, 0x30, 0xE0, 0x1F, 0x12, 0x87, 0xCF, 0x20, 0xE0, 0x02, 0xD1, -0xDA, 0x90, 0xA1, 0x18, 0xE0, 0xB4, 0x02, 0x04, 0x7D, 0x09, 0x80, 0x28, 0x90, 0xA1, 0x18, 0xE0, -0x64, 0x05, 0x70, 0x25, 0x7D, 0x0F, 0x80, 0x1C, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x1B, 0xD1, 0xDA, -0x90, 0xA1, 0x18, 0xE0, 0xB4, 0x02, 0x04, 0x7D, 0x0A, 0x80, 0x09, 0x90, 0xA1, 0x18, 0xE0, 0xB4, -0x05, 0x07, 0x7D, 0x10, 0x7F, 0x6F, 0x12, 0x49, 0x1D, 0x90, 0x9F, 0xCD, 0xE0, 0x30, 0xE0, 0x03, -0x12, 0x5C, 0x9B, 0x90, 0x9F, 0xCD, 0xE0, 0x12, 0x56, 0xCD, 0x30, 0xE0, 0x05, 0xE4, 0xFF, 0x12, -0x8F, 0xCD, 0x90, 0x9F, 0xCE, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x0E, 0x90, 0x06, 0xCD, 0xE0, 0x54, -0xEF, 0xF0, 0x90, 0x06, 0xCF, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x7F, 0x2C, 0x7E, 0x09, 0x02, 0x38, -0x45, 0xFF, 0xEC, 0x90, 0xA1, 0xA1, 0x02, 0x08, 0x6D, 0x90, 0xA0, 0x1A, 0xE0, 0x54, 0x03, 0xFC, -0x22, 0x90, 0xA1, 0x9D, 0x12, 0x45, 0x71, 0xEF, 0x22, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x80, 0xFF, -0x22, 0x90, 0xA0, 0x1A, 0xE0, 0xC4, 0x54, 0x03, 0xFC, 0x22, 0x90, 0x9F, 0x19, 0xE0, 0xFF, 0xE4, -0xFD, 0x02, 0x5A, 0xA8, 0xF0, 0x90, 0x9F, 0xBB, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22, 0x7D, -0x12, 0x7F, 0xFF, 0x12, 0x49, 0x1D, 0x7F, 0x01, 0x51, 0x14, 0xF1, 0xBF, 0x41, 0xCD, 0xFF, 0xE4, -0xFE, 0xFD, 0xFC, 0x90, 0xA1, 0x2A, 0x12, 0x08, 0x6D, 0x90, 0xA1, 0x2A, 0x12, 0x45, 0x71, 0xEC, -0x4D, 0x4E, 0x4F, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA0, 0x20, 0xE0, 0xB4, -0x01, 0x02, 0x80, 0x43, 0x90, 0xA0, 0x20, 0xE0, 0xB4, 0x02, 0x11, 0xF1, 0x89, 0x7F, 0x01, 0x12, -0x97, 0xD0, 0x71, 0xF4, 0x90, 0xA0, 0x20, 0x74, 0x03, 0xF0, 0x80, 0x3E, 0x90, 0xA0, 0x20, 0xE0, -0x64, 0x03, 0x70, 0x1C, 0x90, 0xA0, 0x23, 0xF1, 0x8C, 0xE4, 0xFF, 0x12, 0x97, 0xD0, 0x71, 0xF4, -0xF1, 0x7F, 0xE4, 0xFB, 0xFD, 0x12, 0x4E, 0x53, 0x90, 0xA0, 0x20, 0x74, 0x04, 0xF0, 0x80, 0x1A, -0x90, 0xA0, 0x20, 0xE0, 0xB4, 0x04, 0x13, 0xF1, 0x7F, 0x7B, 0x01, 0x7D, 0x01, 0x12, 0x4E, 0x53, -0x90, 0xA0, 0x20, 0x74, 0x02, 0xF0, 0x90, 0xA0, 0x1E, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, -0xA0, 0x19, 0xE0, 0xC3, 0x13, 0x54, 0x03, 0xFF, 0x22, 0x90, 0xA0, 0x25, 0xE0, 0xFE, 0xA3, 0xE0, -0xFF, 0xAD, 0x07, 0xEE, 0xFF, 0x90, 0x01, 0x6F, 0xE4, 0xF0, 0x8F, 0x35, 0xAF, 0x05, 0x8F, 0x36, -0xFB, 0xFD, 0x7F, 0x6C, 0x7E, 0x01, 0x12, 0x3C, 0xB1, 0x90, 0x01, 0x6F, 0x74, 0x05, 0xF0, 0x22, -0x7D, 0x20, 0x51, 0x4D, 0x90, 0x9F, 0x11, 0x74, 0x02, 0xF0, 0x22, 0x51, 0x52, 0x80, 0xF5, 0x90, -0xA0, 0x0C, 0xE0, 0xFF, 0xE4, 0xFD, 0x22, 0x12, 0x9A, 0x83, 0x7D, 0x23, 0x51, 0x4D, 0x80, 0xE4, -0x90, 0x9F, 0xE6, 0xE0, 0x30, 0xE0, 0x04, 0xD1, 0xEF, 0x80, 0x03, 0x12, 0x85, 0xD6, 0x90, 0xA0, -0x19, 0xE0, 0x30, 0xE0, 0x02, 0xF1, 0x14, 0x22, 0xE4, 0x90, 0xA0, 0xE0, 0xF0, 0x90, 0xA0, 0xE0, -0xE0, 0x64, 0x01, 0xF0, 0x24, 0xE8, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x67, 0xA3, 0xF0, 0x12, 0x3E, -0x44, 0xBF, 0x01, 0x03, 0x12, 0x31, 0xFC, 0xC2, 0xAF, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x0E, 0x90, -0x9F, 0x1A, 0xE0, 0xFF, 0x90, 0x9F, 0x19, 0xE0, 0x6F, 0x60, 0x02, 0x11, 0x3E, 0xC2, 0xAF, 0x12, -0xA0, 0x0F, 0xBF, 0x01, 0x03, 0x12, 0x8E, 0xDD, 0xD2, 0xAF, 0xD2, 0xAF, 0x90, 0xA0, 0x59, 0xE0, -0xB4, 0x01, 0x03, 0x12, 0xA6, 0x03, 0x12, 0x4F, 0xFD, 0x12, 0x42, 0xDD, 0x80, 0xAF, 0x90, 0x9F, -0x0E, 0xE0, 0x90, 0x9F, 0x19, 0x30, 0xE0, 0x04, 0xE0, 0xFF, 0xE1, 0xB5, 0xE0, 0xFF, 0x7D, 0x01, -0x02, 0x5A, 0xA8, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0xDF, 0x90, 0x05, 0x27, 0xE0, -0xF5, 0x54, 0xB1, 0xF7, 0x90, 0x9F, 0x0E, 0xB1, 0x01, 0x91, 0xF2, 0x90, 0x9F, 0x0E, 0xF1, 0x03, -0x91, 0xEC, 0xF1, 0x27, 0x90, 0x9F, 0x0E, 0xF1, 0x0C, 0x91, 0xEC, 0xFE, 0x54, 0x40, 0xFD, 0xEF, -0x54, 0xBF, 0x4D, 0x90, 0x9F, 0x0E, 0xF0, 0xEE, 0xC3, 0x13, 0x20, 0xE0, 0x02, 0x21, 0x0F, 0xE0, -0x30, 0xE0, 0x6A, 0x75, 0x54, 0x21, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x04, 0xD1, 0x25, 0x80, -0x0D, 0xE4, 0x90, 0x9F, 0x0F, 0xF0, 0xA3, 0xF0, 0x7D, 0x40, 0xFF, 0x12, 0x5F, 0x65, 0x31, 0xD5, -0x30, 0xE0, 0x03, 0x43, 0x54, 0x12, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x43, 0x54, 0x14, -0x90, 0x9F, 0x0E, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x03, 0x43, 0x54, 0x80, 0x90, 0x9F, -0x0E, 0x12, 0x4F, 0xD2, 0x20, 0xE0, 0x03, 0x43, 0x54, 0x40, 0x31, 0xC3, 0x90, 0x9F, 0x11, 0xE0, -0x70, 0x05, 0x7F, 0x01, 0x12, 0x99, 0x15, 0x31, 0xCA, 0x30, 0xE0, 0x04, 0x7F, 0x04, 0x80, 0x1A, -0xD1, 0x19, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0x80, 0x11, 0x7F, 0x02, 0x80, 0x0D, 0x31, 0xC0, 0x90, -0x9F, 0x11, 0xE0, 0x64, 0x04, 0x60, 0x02, 0x21, 0xA3, 0xFF, 0x12, 0x99, 0x15, 0x21, 0xA3, 0x90, -0x9F, 0x0E, 0xE0, 0xFF, 0x30, 0xE0, 0x65, 0x43, 0x54, 0x31, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, -0x04, 0xD1, 0x25, 0x80, 0x07, 0x7D, 0x40, 0xE4, 0xFF, 0x12, 0x5F, 0x65, 0x31, 0xD5, 0x30, 0xE0, -0x03, 0x43, 0x54, 0x02, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x43, 0x54, 0x04, 0x31, 0xC3, -0x31, 0xCA, 0x30, 0xE0, 0x0A, 0xD1, 0xE5, 0x60, 0x5A, 0xE4, 0xFD, 0x7F, 0x02, 0x80, 0x1E, 0x12, -0x9A, 0x83, 0x90, 0x9F, 0x12, 0xE0, 0xB4, 0x02, 0x19, 0x12, 0x9A, 0xAE, 0xD1, 0x19, 0xBF, 0x01, -0x09, 0x90, 0x9F, 0x19, 0xE0, 0xFF, 0x7D, 0x01, 0x80, 0x03, 0xE4, 0xFD, 0xFF, 0x12, 0x5A, 0xA8, -0x80, 0x31, 0x90, 0x9F, 0x1A, 0xE0, 0x90, 0x9F, 0x12, 0xF0, 0x80, 0x27, 0x31, 0xC0, 0x90, 0x9F, -0x12, 0xE0, 0xB4, 0x02, 0x06, 0x7D, 0x01, 0x7F, 0x04, 0x80, 0x0B, 0x90, 0x9F, 0x12, 0xE0, 0xB4, -0x08, 0x07, 0x7D, 0x01, 0x7F, 0x0C, 0x12, 0x5A, 0xA8, 0xF1, 0x1E, 0x90, 0x9F, 0x19, 0x11, 0x4C, -0x12, 0xA6, 0x83, 0x90, 0x9F, 0x13, 0xE0, 0x20, 0xE0, 0x08, 0x90, 0x05, 0x58, 0x74, 0x01, 0xF0, -0x80, 0x03, 0x12, 0x95, 0x38, 0x90, 0x05, 0x40, 0x74, 0x22, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, -0x75, 0x54, 0x01, 0x90, 0x05, 0x27, 0xE5, 0x54, 0xF0, 0x22, 0x90, 0x9F, 0x0E, 0xE0, 0xFF, 0xC4, -0x13, 0x13, 0x54, 0x03, 0x22, 0x90, 0x9F, 0x0E, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0xD2, 0xB1, 0xF7, 0x90, 0x9F, 0xCA, 0xB1, 0x01, -0x91, 0xF2, 0x90, 0x9F, 0xCA, 0x91, 0xE4, 0xD1, 0x0F, 0x90, 0x9F, 0xCA, 0xB1, 0xE3, 0x91, 0xEC, -0xD1, 0x07, 0x90, 0x9F, 0xCA, 0xF0, 0x12, 0x56, 0xE7, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x9F, 0xCD, -0xB1, 0x01, 0xFF, 0xF0, 0x12, 0x56, 0xE7, 0x91, 0xF7, 0x90, 0x9F, 0xCD, 0xF0, 0xEE, 0x54, 0x10, -0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x12, 0x56, 0xE7, 0xD1, 0x0F, 0x90, 0x9F, 0xCD, 0xB1, -0xE3, 0x4E, 0xFF, 0xF0, 0x12, 0x56, 0xE7, 0xD1, 0x07, 0x90, 0x9F, 0xCD, 0x91, 0xDD, 0xFF, 0x54, -0x20, 0xFE, 0x90, 0x9F, 0xCE, 0xE0, 0x54, 0xDF, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x40, 0xFF, 0xEE, -0x54, 0xBF, 0x4F, 0x91, 0xDC, 0xFE, 0x54, 0x80, 0xFD, 0xEF, 0x54, 0x7F, 0x4D, 0xFF, 0x90, 0x9F, -0xCE, 0xF0, 0xEE, 0x54, 0x01, 0xFE, 0xEF, 0x54, 0xFE, 0x4E, 0x91, 0xDC, 0x91, 0xF7, 0x90, 0x9F, -0xCE, 0xF0, 0xEE, 0x54, 0x02, 0xFE, 0xEF, 0x54, 0xFD, 0x4E, 0x91, 0xDC, 0xF1, 0x27, 0x90, 0x9F, -0xCE, 0xF1, 0x03, 0x4E, 0xF0, 0xD1, 0xBB, 0x20, 0xE0, 0x06, 0x12, 0x5F, 0x71, 0x12, 0x5C, 0x9B, -0x12, 0x5E, 0x32, 0x12, 0x06, 0x89, 0x20, 0xE0, 0x02, 0x61, 0xDE, 0x90, 0x05, 0x54, 0xE0, 0x90, -0x9F, 0xDC, 0xF0, 0xE0, 0xC3, 0x13, 0x90, 0x9F, 0xDB, 0x12, 0x84, 0xA9, 0x30, 0xE0, 0x0F, 0x12, -0x57, 0xC5, 0x90, 0x9F, 0xCB, 0x12, 0x56, 0xBB, 0x90, 0x9F, 0xCC, 0xF0, 0x80, 0x42, 0x12, 0x57, -0xC5, 0xFF, 0xC3, 0x94, 0x2A, 0x50, 0x12, 0xEF, 0xC3, 0x94, 0x03, 0x90, 0x9F, 0xCB, 0x50, 0x05, -0x74, 0x03, 0xF0, 0x80, 0x0A, 0xEF, 0xF0, 0x80, 0x06, 0x90, 0x9F, 0xCB, 0x74, 0x2A, 0xF0, 0x12, -0x56, 0xBC, 0xFF, 0xC3, 0x94, 0x2A, 0x50, 0x12, 0xEF, 0xC3, 0x94, 0x03, 0x90, 0x9F, 0xCC, 0x50, -0x05, 0x74, 0x03, 0xF0, 0x80, 0x0A, 0xEF, 0xF0, 0x80, 0x06, 0x90, 0x9F, 0xCC, 0x74, 0x2A, 0xF0, -0x12, 0x4F, 0xCF, 0x30, 0xE0, 0x3C, 0x90, 0x9F, 0xCB, 0xE0, 0x75, 0xF0, 0x03, 0x84, 0x90, 0x9F, -0xD4, 0xF0, 0xE0, 0xC3, 0x13, 0xA3, 0xF0, 0x90, 0x9F, 0xCC, 0xE0, 0x75, 0xF0, 0x03, 0x84, 0x90, -0x9F, 0xD6, 0xF0, 0x90, 0x9F, 0xCB, 0xE0, 0xC3, 0x13, 0x90, 0x9F, 0xD7, 0xF0, 0x90, 0x9F, 0xCC, -0xE0, 0xC3, 0x13, 0x90, 0x9F, 0xD8, 0xF0, 0x90, 0x01, 0x3E, 0x74, 0x08, 0xF0, 0xFD, 0x7F, 0x02, -0xF1, 0x56, 0xE4, 0x90, 0xA0, 0x0A, 0xF0, 0x12, 0x56, 0xE1, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, -0xE0, 0x39, 0x90, 0x9F, 0xCA, 0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0, 0x07, 0xEF, 0x12, 0x56, 0xCD, -0x30, 0xE0, 0x28, 0x12, 0x06, 0x89, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x08, 0x90, 0xA0, -0x0C, 0xE0, 0x60, 0x08, 0x80, 0x0B, 0x90, 0xA0, 0x0C, 0xE0, 0x60, 0x05, 0x75, 0x51, 0x01, 0x80, -0x03, 0xE4, 0xF5, 0x51, 0x7D, 0x02, 0xAF, 0x51, 0x12, 0x62, 0xCD, 0x12, 0x86, 0x13, 0x30, 0xE0, -0x12, 0x12, 0x87, 0xCF, 0x30, 0xE0, 0x07, 0x7D, 0x04, 0x7F, 0x02, 0x12, 0x5A, 0x26, 0xB1, 0xFF, -0x74, 0x11, 0xF0, 0x90, 0x05, 0x58, 0x74, 0x02, 0xF0, 0x90, 0x9F, 0xD3, 0xE0, 0xFF, 0xB4, 0x01, -0x08, 0x90, 0x9F, 0xDE, 0x74, 0x01, 0xF0, 0x80, 0x1E, 0xEF, 0xB4, 0x04, 0x08, 0x90, 0x9F, 0xDE, -0x74, 0x04, 0xF0, 0x80, 0x12, 0xEF, 0xB4, 0x06, 0x08, 0x90, 0x9F, 0xDE, 0x74, 0x02, 0xF0, 0x80, -0x06, 0xEF, 0xB4, 0x07, 0x02, 0xF1, 0xD8, 0xE4, 0x90, 0x9F, 0xD3, 0xF0, 0x80, 0x4A, 0x12, 0x56, -0xE1, 0x31, 0xCE, 0x30, 0xE0, 0x05, 0x75, 0x52, 0x02, 0x80, 0x10, 0x12, 0x06, 0x89, 0x31, 0xD9, -0x30, 0xE0, 0x05, 0x75, 0x52, 0x01, 0x80, 0x03, 0xE4, 0xF5, 0x52, 0x12, 0x98, 0x24, 0x7D, 0x2C, -0x7F, 0x40, 0x12, 0x46, 0xA0, 0x12, 0x56, 0xE1, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x04, -0x7F, 0x03, 0x80, 0x02, 0x7F, 0x01, 0x12, 0x62, 0x14, 0xAD, 0x52, 0x7F, 0x02, 0x12, 0x62, 0xCD, -0x12, 0x5C, 0x9B, 0xB1, 0xFF, 0x74, 0x43, 0xF0, 0x12, 0xAA, 0x26, 0x90, 0x9F, 0xDD, 0xF0, 0x90, -0x9F, 0xCD, 0xE0, 0x12, 0x56, 0xCD, 0x30, 0xE0, 0x09, 0x90, 0x9F, 0xFD, 0xE0, 0x44, 0x02, 0xF0, -0x80, 0x0C, 0x7F, 0x01, 0x12, 0x8F, 0xCD, 0x90, 0x9F, 0xFD, 0xE0, 0x54, 0xFD, 0xF0, 0x7F, 0x03, -0x12, 0x97, 0xD0, 0x90, 0x9F, 0xCA, 0xE0, 0x20, 0xE0, 0x07, 0x90, 0x9F, 0xCE, 0xE0, 0x54, 0xBF, -0xF0, 0x90, 0x9F, 0xCF, 0xE0, 0x20, 0xE0, 0x6F, 0x12, 0x5E, 0x32, 0x12, 0x5E, 0x3B, 0x30, 0xE0, -0x66, 0x90, 0x00, 0x40, 0xE0, 0x54, 0xBF, 0x44, 0xA0, 0xFD, 0x7F, 0x40, 0x12, 0x46, 0xA0, 0x90, -0x00, 0x41, 0xE0, 0x44, 0x04, 0xFD, 0x7F, 0x41, 0x12, 0x46, 0xA0, 0x90, 0x00, 0x6A, 0xE0, 0x54, -0xFB, 0xFD, 0x7F, 0x6A, 0x12, 0x46, 0xA0, 0x90, 0x07, 0x6E, 0x74, 0x55, 0xF0, 0xA3, 0x74, 0x12, -0xF0, 0x90, 0x07, 0x78, 0xE0, 0x54, 0xF2, 0x44, 0x02, 0xF0, 0x90, 0x06, 0xCC, 0xE0, 0x44, 0x03, -0xF0, 0x90, 0x07, 0x65, 0xE0, 0x54, 0xF5, 0xF0, 0x90, 0x05, 0x23, 0xE0, 0x54, 0x7F, 0xF0, 0xE4, -0xFD, 0x7F, 0x66, 0x12, 0x46, 0xA0, 0x12, 0x5E, 0x32, 0x12, 0x5E, 0x3B, 0x54, 0x01, 0xFF, 0x90, -0x9F, 0xCF, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xFF, 0xF0, 0x90, 0x00, -0x04, 0x02, 0x06, 0xA2, 0xF0, 0xEE, 0x54, 0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x02, -0x06, 0x89, 0xFF, 0xF0, 0x12, 0x06, 0x89, 0xFE, 0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0xFF, -0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F, 0x22, -0xB1, 0xF7, 0x90, 0xA0, 0x19, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x06, 0xFF, 0xEE, -0x54, 0xF9, 0x4F, 0xFF, 0xF0, 0x12, 0x06, 0x89, 0xFE, 0x54, 0x08, 0xFD, 0xEF, 0x54, 0xF7, 0x4D, -0xFF, 0x90, 0xA0, 0x19, 0x91, 0xE4, 0xF1, 0x0E, 0x4E, 0x90, 0xA0, 0x19, 0x12, 0x57, 0xC4, 0xFF, -0x54, 0x03, 0xFE, 0x90, 0xA0, 0x1A, 0xE0, 0x54, 0xFC, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x04, 0xFF, -0xEE, 0x54, 0xFB, 0x4F, 0xFF, 0x12, 0x57, 0xC4, 0xFE, 0x54, 0x30, 0xFD, 0xEF, 0x54, 0xCF, 0x4D, -0xFF, 0x90, 0xA0, 0x1A, 0xB1, 0xE3, 0x4E, 0x12, 0x56, 0xBB, 0x90, 0xA0, 0x1B, 0xF0, 0x12, 0x56, -0xE7, 0x90, 0xA0, 0x1C, 0x91, 0xDD, 0x90, 0xA0, 0x1D, 0xF0, 0x90, 0xA0, 0x1B, 0xB1, 0xEC, 0xEF, -0x78, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0xA0, 0x23, 0xEE, 0xF0, 0xA3, -0xEF, 0xF0, 0x90, 0xA0, 0x1C, 0xB1, 0xEC, 0xEF, 0x78, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, -0xF9, 0xFF, 0x90, 0xA0, 0x25, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA0, 0x1D, 0xB1, 0xEC, 0x90, -0xA0, 0x27, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA0, 0x19, 0xE0, 0x30, 0xE0, 0x14, 0x90, 0xA0, -0x1E, 0x74, 0x01, 0xF0, 0xA3, 0xF0, 0xA3, 0x12, 0x8E, 0xC3, 0x90, 0x07, 0x83, 0xE0, 0x44, 0x20, -0xF0, 0x22, 0xE4, 0x90, 0xA0, 0x1E, 0x12, 0x58, 0xB2, 0xA3, 0xF0, 0x90, 0x07, 0x83, 0xE0, 0x54, -0xDF, 0xF0, 0x22, 0xF0, 0xEE, 0x54, 0x40, 0xFE, 0xEF, 0x54, 0xBF, 0x22, 0xE0, 0xFF, 0x7E, 0x00, -0x7C, 0x01, 0x7D, 0x40, 0x02, 0x07, 0x03, 0x12, 0x06, 0x89, 0xFF, 0x54, 0x01, 0xFE, 0x22, 0x90, -0x05, 0x00, 0x74, 0x1C, 0xF0, 0xA3, 0x22, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F, 0x4E, 0x22, 0xFE, -0x54, 0x20, 0xFD, 0xEF, 0x54, 0xDF, 0x4D, 0xFF, 0x22, 0x90, 0x05, 0x43, 0xE0, 0x7F, 0x00, 0x30, -0xE7, 0x02, 0x7F, 0x01, 0x22, 0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x12, 0x5E, -0xB8, 0x43, 0x54, 0x08, 0x22, 0x90, 0x9F, 0x13, 0x31, 0xCD, 0x30, 0xE0, 0x24, 0xEF, 0x54, 0xBF, -0xF1, 0x15, 0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFE, 0xF0, 0x90, -0x9F, 0xD1, 0x12, 0x86, 0x27, 0x30, 0xE0, 0x07, 0x7D, 0x01, 0x7F, 0x0C, 0x02, 0x5A, 0xA8, 0x11, -0x3E, 0x22, 0x90, 0x9F, 0x13, 0xE0, 0x12, 0x56, 0xCC, 0x30, 0xE0, 0x1A, 0xEF, 0x54, 0x7F, 0xF1, -0x15, 0x30, 0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x9F, -0x17, 0xE0, 0x60, 0x02, 0x11, 0x3E, 0x90, 0x9F, 0xCE, 0x31, 0xCD, 0x30, 0xE0, 0x22, 0x90, 0x9F, -0xD2, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, 0x18, 0xEF, 0x54, 0xFD, 0xF0, 0x90, 0x04, 0xE0, 0xE0, -0x90, 0x9F, 0xD2, 0x30, 0xE1, 0x06, 0xE0, 0x44, 0x04, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFB, 0xF0, -0x90, 0x04, 0xE0, 0xE0, 0x30, 0xE1, 0x03, 0x12, 0xA5, 0xCB, 0x22, 0xE0, 0xFF, 0x13, 0x13, 0x54, -0x3F, 0x22, 0x90, 0x9F, 0x13, 0xD1, 0xBB, 0x30, 0xE0, 0x09, 0x12, 0x91, 0xF6, 0x54, 0x07, 0x70, -0x13, 0x80, 0x0F, 0x12, 0x95, 0x42, 0x40, 0x0A, 0x90, 0x9E, 0x8D, 0xE0, 0xB4, 0x01, 0x05, 0x02, -0x97, 0x49, 0x11, 0x3E, 0x22, 0x90, 0x9F, 0x12, 0xE0, 0x64, 0x02, 0x22, 0x31, 0xCA, 0x30, 0xE0, -0x0B, 0xD1, 0xE5, 0x60, 0x07, 0x7D, 0x01, 0x7F, 0x02, 0x12, 0x5A, 0xA8, 0xD1, 0xE5, 0x60, 0x02, -0xF1, 0x76, 0x22, 0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x22, 0xF0, 0xEE, 0x54, 0x20, -0xFE, 0xEF, 0x54, 0xDF, 0x22, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x9F, 0x14, 0x22, 0xF1, 0x9C, -0xEF, 0x70, 0x03, 0x12, 0x5C, 0xD8, 0x22, 0xFE, 0x54, 0x10, 0xFD, 0xEF, 0x54, 0xEF, 0x4D, 0xFF, -0x22, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x0F, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1, 0x03, 0x02, 0x93, -0x8A, 0x12, 0x5E, 0xC9, 0x11, 0x3E, 0x22, 0xEF, 0x14, 0x90, 0x05, 0x73, 0xF0, 0x90, 0x01, 0x3F, -0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, 0x74, 0x1D, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x38, -0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0x7D, 0x20, 0xE4, 0xFF, 0x74, -0x1D, 0x12, 0xAA, 0x89, 0x80, 0xE6, 0x90, 0x9F, 0x17, 0xE0, 0x64, 0x02, 0x60, 0x0F, 0xF1, 0x95, -0x60, 0x0B, 0xF1, 0x9C, 0xEF, 0x70, 0x06, 0xFD, 0x7F, 0x0C, 0x12, 0x5A, 0xA8, 0x22, 0x90, 0x9F, -0x1B, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x9F, 0x15, 0xE0, 0x54, 0x0F, 0x22, 0x90, 0x04, 0x1A, 0xE0, -0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x04, 0x1B, 0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F, 0x01, -0x60, 0x02, 0x7F, 0x00, 0x22, 0xAE, 0x07, 0xD1, 0x19, 0xBF, 0x01, 0x13, 0x90, 0x9F, 0x0E, 0x12, -0x4F, 0xD2, 0x20, 0xE0, 0x0A, 0xAF, 0x06, 0x7D, 0x01, 0x12, 0x5A, 0xA8, 0x7F, 0x01, 0x22, 0x7F, -0x00, 0x22, 0x90, 0xA0, 0xEE, 0x02, 0x45, 0xBE, 0x90, 0x9F, 0xDE, 0x74, 0x05, 0xF0, 0x22, 0x8B, -0x51, 0x8A, 0x52, 0x89, 0x53, 0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x44, 0xDE, 0x90, -0xA0, 0xE9, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x9D, 0x93, 0xE0, 0x60, 0xEA, 0xC2, 0xAF, 0x30, 0xE0, -0x0A, 0x54, 0xFE, 0xF0, 0xE4, 0xFF, 0x12, 0x7E, 0xDA, 0x11, 0x30, 0xB1, 0xC7, 0x30, 0xE1, 0x06, -0x54, 0xFD, 0xF0, 0x12, 0x9D, 0x1F, 0xB1, 0xC7, 0x30, 0xE2, 0x06, 0x54, 0xFB, 0xF0, 0x12, 0x9E, -0xD2, 0xB1, 0xC7, 0x30, 0xE6, 0x06, 0x54, 0xBF, 0xF0, 0x12, 0x87, 0x85, 0xD2, 0xAF, 0x80, 0xC6, -0xE4, 0xF5, 0x51, 0x74, 0x8D, 0x25, 0x51, 0x12, 0x95, 0xF8, 0xE0, 0x70, 0x02, 0xA1, 0x7C, 0x12, -0x51, 0x02, 0x12, 0x56, 0xCC, 0x30, 0xE0, 0x02, 0xA1, 0x7C, 0xE5, 0x51, 0xF1, 0xD7, 0xE0, 0xFE, -0xA3, 0xE0, 0xD3, 0x94, 0x00, 0xEE, 0x94, 0x00, 0x50, 0x02, 0xA1, 0x7C, 0xE5, 0x51, 0x75, 0xF0, -0x0A, 0xA4, 0x24, 0x01, 0xF9, 0x74, 0x8D, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x90, 0xA0, 0xED, 0x12, -0x45, 0xBE, 0xE5, 0x51, 0xF1, 0xD7, 0xE0, 0xF5, 0x56, 0xA3, 0xE0, 0xF5, 0x57, 0x74, 0x12, 0x25, -0x51, 0x12, 0xA3, 0x5F, 0xE0, 0xFF, 0x90, 0xA0, 0xF0, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x00, -0x02, 0x12, 0x07, 0xAB, 0xFF, 0xAE, 0xF0, 0x12, 0x07, 0x80, 0x2F, 0xFF, 0xE5, 0xF0, 0x3E, 0xFE, -0x90, 0x00, 0x04, 0xB1, 0xBE, 0xFE, 0x90, 0x00, 0x06, 0xB1, 0xBE, 0xFE, 0x90, 0x00, 0x08, 0xB1, -0xBE, 0x90, 0xA0, 0xF2, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x07, 0x80, 0xFF, 0xC3, 0x90, 0xA0, 0xF3, -0xE0, 0x9F, 0xFE, 0x90, 0xA0, 0xF2, 0xE0, 0x95, 0xF0, 0x90, 0xA0, 0xF4, 0xF0, 0xA3, 0xCE, 0xF0, -0x90, 0x00, 0x06, 0x12, 0x07, 0xAB, 0xFD, 0xAC, 0xF0, 0x25, 0xE0, 0xFF, 0xEC, 0x33, 0xFE, 0xEF, -0x2D, 0xFD, 0xEE, 0x3C, 0xFC, 0x90, 0x00, 0x04, 0x12, 0x07, 0xAB, 0x25, 0xE0, 0xFF, 0xE5, 0xF0, -0x33, 0xFE, 0x90, 0x00, 0x02, 0xB1, 0xBE, 0xCF, 0x2D, 0xFD, 0xEF, 0x3C, 0xFC, 0xB1, 0xA3, 0xF1, -0x5A, 0xAE, 0xF0, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x2D, 0xFF, 0xEC, 0x3E, -0x90, 0xA0, 0xF6, 0x12, 0xAA, 0x71, 0xE5, 0x51, 0x12, 0x7F, 0xBC, 0xF5, 0x52, 0x54, 0x7F, 0xF5, -0x53, 0x75, 0xF0, 0x04, 0xE5, 0x51, 0xF1, 0x94, 0xE0, 0x90, 0xA0, 0xF8, 0xF0, 0x12, 0x51, 0x02, -0xFF, 0x13, 0x13, 0x54, 0x03, 0x90, 0xA0, 0xF9, 0xF0, 0xB1, 0x8A, 0xE0, 0xC3, 0x94, 0x05, 0x40, -0x02, 0x61, 0xB4, 0x90, 0xA0, 0xF8, 0xE0, 0xFF, 0xE5, 0x53, 0x9F, 0x40, 0x08, 0x8F, 0x53, 0x53, -0x52, 0x80, 0xEF, 0x42, 0x52, 0xE5, 0x53, 0x90, 0x41, 0x5F, 0x93, 0xB1, 0x96, 0xE0, 0xC3, 0x9F, -0xE5, 0x53, 0x40, 0x05, 0x90, 0x41, 0x37, 0x80, 0x03, 0x90, 0x41, 0x4B, 0x93, 0xF5, 0x58, 0x90, -0xA0, 0x0E, 0xE0, 0x60, 0x7D, 0xE5, 0x53, 0x64, 0x13, 0x60, 0x05, 0xE5, 0x53, 0xB4, 0x0B, 0x05, -0x90, 0xA0, 0x10, 0x80, 0x23, 0xE5, 0x53, 0x64, 0x12, 0x60, 0x05, 0xE5, 0x53, 0xB4, 0x0A, 0x05, -0x90, 0xA0, 0x11, 0x80, 0x13, 0xE5, 0x53, 0x64, 0x11, 0x60, 0x05, 0xE5, 0x53, 0xB4, 0x09, 0x05, -0x90, 0xA0, 0x12, 0x80, 0x03, 0x90, 0xA0, 0x0F, 0xE0, 0xF5, 0x5C, 0xE5, 0x5C, 0xC3, 0x94, 0x80, -0x50, 0x28, 0xE5, 0x5C, 0x94, 0x1B, 0x40, 0x02, 0x80, 0x13, 0xE5, 0x58, 0x25, 0x5C, 0xFF, 0xE4, -0x33, 0xFE, 0xD3, 0xEF, 0x94, 0x1B, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x40, 0x05, 0x75, 0x58, 0x1B, -0x80, 0x20, 0xE5, 0x5C, 0x25, 0x58, 0xF5, 0x58, 0x80, 0x18, 0xC3, 0xE4, 0x95, 0x5C, 0xF5, 0x5C, -0xE5, 0x58, 0xD3, 0x95, 0x5C, 0x40, 0x08, 0xE5, 0x58, 0x95, 0x5C, 0xF5, 0x58, 0x80, 0x03, 0xE4, -0xF5, 0x58, 0xE5, 0x58, 0x75, 0xF0, 0x06, 0xA4, 0x24, 0x95, 0xF9, 0x74, 0x40, 0x35, 0xF0, 0xFA, -0x7B, 0xFF, 0x90, 0xA0, 0xEA, 0x12, 0x45, 0xBE, 0xC3, 0xE5, 0x57, 0x94, 0x0F, 0xE5, 0x56, 0x94, -0x00, 0x50, 0x7B, 0xB1, 0xA3, 0x90, 0x00, 0x06, 0x12, 0x07, 0xAB, 0xFF, 0xAE, 0xF0, 0xF1, 0x5A, -0x2F, 0xFD, 0xE5, 0xF0, 0x3E, 0xFC, 0xB1, 0xB5, 0xFF, 0xD3, 0xED, 0x9F, 0xEC, 0x9E, 0x40, 0x02, -0x61, 0x8C, 0xE5, 0x57, 0xAE, 0x56, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFD, -0xAC, 0x06, 0xB1, 0xB5, 0x2D, 0xFF, 0xEE, 0x3C, 0xFE, 0xB1, 0xA3, 0x12, 0x07, 0x80, 0xD3, 0x9F, -0xE5, 0xF0, 0x9E, 0x50, 0x02, 0x61, 0x93, 0xE5, 0x53, 0xD3, 0x94, 0x38, 0x50, 0x0A, 0xB1, 0x97, -0xE0, 0xC3, 0x94, 0x0F, 0x50, 0x02, 0x61, 0x93, 0xE5, 0x53, 0xD3, 0x94, 0x3A, 0x50, 0x0A, 0xB1, -0x97, 0xE0, 0xC3, 0x94, 0x14, 0x50, 0x02, 0x61, 0x93, 0xE5, 0x53, 0xD3, 0x94, 0x3C, 0x40, 0x02, -0x61, 0x75, 0xB1, 0x97, 0xE0, 0xC3, 0x94, 0x19, 0x50, 0x02, 0x61, 0x93, 0x61, 0x75, 0xE5, 0x51, -0x70, 0x3C, 0xB1, 0xA3, 0xF1, 0x5A, 0xFD, 0xAC, 0xF0, 0xB1, 0xB5, 0xFF, 0xC3, 0xED, 0x9F, 0xEC, -0x9E, 0x50, 0x08, 0x90, 0x9D, 0x92, 0x74, 0x01, 0xF0, 0x80, 0x23, 0xE5, 0x57, 0xAE, 0x56, 0x78, -0x03, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFB, 0xAA, 0x06, 0xB1, 0xB5, 0x2B, 0xFF, 0xEE, -0x3A, 0xFE, 0xD3, 0xED, 0x9F, 0xEC, 0x9E, 0x40, 0x05, 0xE4, 0x90, 0x9D, 0x92, 0xF0, 0xF1, 0x85, -0x40, 0x05, 0x75, 0x59, 0x05, 0x80, 0x13, 0xD3, 0xE5, 0x57, 0x94, 0xC8, 0xE5, 0x56, 0x94, 0x00, -0x40, 0x05, 0x75, 0x59, 0x02, 0x80, 0x03, 0xE4, 0xF5, 0x59, 0xE5, 0x51, 0xF1, 0x50, 0xF5, 0x83, -0xE0, 0xF5, 0x54, 0xA3, 0xE0, 0xF5, 0x55, 0xE4, 0xF5, 0x5D, 0xB1, 0xA3, 0x75, 0xF0, 0x02, 0xE5, -0x5D, 0x12, 0xA9, 0x5E, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0xA0, -0xEA, 0x12, 0x45, 0xB5, 0x85, 0x5D, 0x82, 0x75, 0x83, 0x00, 0x12, 0x06, 0xA2, 0x12, 0xA9, 0x3E, -0x05, 0x5D, 0xE5, 0x5D, 0xB4, 0x05, 0xD3, 0x90, 0xA0, 0xEA, 0x12, 0x45, 0xB5, 0x12, 0x5E, 0x3B, -0xFD, 0x7C, 0x00, 0xF1, 0x74, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x12, -0x07, 0x03, 0xD3, 0xE5, 0x55, 0x9F, 0xE5, 0x54, 0x9E, 0x40, 0x0C, 0xE5, 0x55, 0x9F, 0xF5, 0x55, -0xE5, 0x54, 0x9E, 0xF5, 0x54, 0x80, 0x05, 0xE4, 0xF5, 0x54, 0xF5, 0x55, 0xE5, 0x51, 0xF1, 0x50, -0xF5, 0x83, 0x12, 0x9C, 0xCB, 0xAE, 0x54, 0xFF, 0xE4, 0xFC, 0xFD, 0xE5, 0x53, 0xF1, 0xE3, 0xC3, -0x12, 0x45, 0x60, 0x50, 0x07, 0xAF, 0x51, 0x12, 0x7A, 0xE4, 0x80, 0x17, 0xE5, 0x53, 0xF1, 0xB1, -0xD3, 0x74, 0x01, 0x93, 0x95, 0x55, 0xE4, 0x93, 0x95, 0x54, 0x40, 0x07, 0x7D, 0x01, 0xAF, 0x51, -0x12, 0x7B, 0xEF, 0xE5, 0x51, 0xF1, 0x50, 0xF5, 0x83, 0xA3, 0xE0, 0x90, 0xA1, 0x3B, 0xF0, 0x90, -0xA1, 0x3A, 0xE5, 0x52, 0xF0, 0xAB, 0x51, 0xE4, 0xFD, 0xFF, 0x12, 0x8B, 0xE5, 0xE4, 0xF5, 0x54, -0xF5, 0x55, 0xA1, 0x60, 0xB1, 0x8A, 0xE0, 0xFC, 0x64, 0x05, 0x60, 0x02, 0x81, 0x6F, 0xAD, 0x53, -0xAF, 0x51, 0x12, 0xA2, 0x78, 0xF1, 0xC9, 0xEF, 0xB1, 0xD1, 0xE0, 0x54, 0x07, 0xF5, 0x5B, 0xB1, -0x97, 0xE0, 0xFF, 0xC3, 0x94, 0x30, 0x50, 0x06, 0xE4, 0xB1, 0x88, 0xE4, 0x80, 0x4E, 0xF1, 0xC9, -0xE0, 0x64, 0x01, 0x70, 0x5E, 0xF1, 0x60, 0xE0, 0x64, 0x0A, 0x60, 0x23, 0xEF, 0x24, 0x05, 0xFF, -0xE4, 0x33, 0xFE, 0xF1, 0xBD, 0xE0, 0xFD, 0xF1, 0x9B, 0x50, 0x14, 0xED, 0x24, 0x05, 0xFF, 0xE4, -0x33, 0xFE, 0xB1, 0x97, 0xF1, 0x9A, 0x50, 0x07, 0xF1, 0xA5, 0xE0, 0x65, 0x53, 0x60, 0x29, 0xE5, +0x41, 0xA2, 0x14, 0x00, 0x41, 0xA2, 0x15, 0x00, 0x41, 0xA2, 0x16, 0x00, 0x41, 0xA2, 0x1A, 0x00, +0x01, 0x70, 0x00, 0x41, 0xA2, 0x1B, 0x00, 0x41, 0xA2, 0x1C, 0x00, 0x41, 0xA2, 0x3D, 0x00, 0x00, +0x5F, 0xFB, 0x67, 0xEE, 0x70, 0x07, 0x7F, 0x67, 0xF1, 0xAF, 0xEF, 0x44, 0x20, 0xFD, 0x7F, 0x67, +0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x82, 0x75, 0x83, 0x00, 0xED, 0xF1, 0xFD, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xF4, 0xEF, 0xF0, +0x90, 0xA1, 0xF6, 0xEB, 0xF0, 0xED, 0x60, 0x02, 0xE1, 0x5A, 0x90, 0x07, 0x6E, 0xE0, 0x44, 0x08, +0xF0, 0x12, 0x9F, 0xA2, 0x90, 0xA1, 0xF6, 0xE0, 0x70, 0x43, 0xD1, 0x96, 0x90, 0xA1, 0xF4, 0xE0, +0x70, 0x35, 0x12, 0xAC, 0xE0, 0x70, 0x16, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0x74, 0x02, 0xFE, 0xEC, +0xF1, 0xD0, 0xF1, 0xD6, 0x7F, 0x64, 0xF1, 0xAF, 0xEF, 0x54, 0xFE, 0x80, 0x15, 0x12, 0x37, 0x4E, +0xE4, 0xFE, 0x74, 0x80, 0xFF, 0xE4, 0xEC, 0xF1, 0xD0, 0xF1, 0xD6, 0x7F, 0x64, 0xF1, 0xAF, 0xEF, +0x44, 0x01, 0xFD, 0x7F, 0x64, 0xD1, 0xA0, 0x7F, 0x4E, 0xF1, 0xF7, 0xE1, 0xA1, 0xD1, 0x96, 0x90, +0xA1, 0xF4, 0xE0, 0x70, 0x0A, 0xF1, 0xF0, 0xE4, 0xFF, 0xFE, 0xEC, 0xF1, 0xD0, 0xF1, 0xD6, 0xF1, +0xE8, 0xF1, 0xDD, 0x44, 0x01, 0xFD, 0x7F, 0x4F, 0xD1, 0xA0, 0x12, 0x97, 0x6E, 0xE4, 0x74, 0x66, +0xFF, 0xEC, 0xF1, 0xD0, 0x7F, 0x30, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x12, 0xAB, 0x8D, 0xEF, 0x44, +0x01, 0xFF, 0xEC, 0xF1, 0xD0, 0x12, 0x67, 0xD1, 0x80, 0x50, 0x90, 0x07, 0x6E, 0xE0, 0x54, 0xF7, +0xF0, 0x12, 0x9F, 0xAA, 0x90, 0xA1, 0xF4, 0xE0, 0x70, 0x35, 0x90, 0xA1, 0xF6, 0xE0, 0x60, 0x08, +0xD1, 0x96, 0xF1, 0xF0, 0xE4, 0xFF, 0x80, 0x21, 0x7F, 0x67, 0xF1, 0xAF, 0xEF, 0x54, 0xDF, 0xFD, +0x7F, 0x67, 0xD1, 0xA0, 0x12, 0xAC, 0xE0, 0x70, 0x0B, 0x12, 0x37, 0x4E, 0xE4, 0x74, 0x80, 0xFF, +0x74, 0x02, 0x80, 0x05, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0xFE, 0xEC, 0xF1, 0xD0, 0xF1, 0xD6, 0xF1, +0xE8, 0xF1, 0xDD, 0x54, 0xFE, 0xFD, 0x7F, 0x4F, 0xD1, 0xA0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x82, 0x75, 0x83, 0x00, 0xE0, 0x90, 0xA2, 0x32, 0xF1, +0xFD, 0x90, 0xA2, 0x32, 0xE0, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA1, 0xC5, 0xB1, 0x71, +0x90, 0xAA, 0xB9, 0x02, 0x08, 0x6D, 0x7F, 0x48, 0x7E, 0x09, 0x02, 0x38, 0x45, 0xFD, 0x7F, 0x4E, +0xD1, 0xA0, 0x7F, 0x4F, 0xF1, 0xAF, 0xEF, 0x22, 0x7F, 0x4E, 0xF1, 0xAF, 0xEF, 0x54, 0x7F, 0x22, +0x7F, 0x48, 0x7E, 0x09, 0x02, 0x37, 0x4E, 0xF1, 0xAF, 0xEF, 0x44, 0x80, 0x22, 0xF0, 0x7F, 0x10, +0x7E, 0x00, 0x02, 0x3E, 0x50, 0x90, 0xA0, 0xC1, 0xE0, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0x75, 0xF0, +0x0E, 0x90, 0xA0, 0xCE, 0x12, 0x45, 0xA9, 0xE0, 0xFE, 0x75, 0xF0, 0x0E, 0xEF, 0x90, 0xA0, 0xCD, +0x12, 0x45, 0xA9, 0xE0, 0x90, 0xA1, 0xDA, 0xF0, 0x90, 0xA1, 0xD9, 0xEE, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x54, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xD5, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0x90, 0xA1, 0xD9, 0xE0, 0xF5, 0x3B, 0xA3, 0xE0, 0xF5, 0x3C, 0x12, 0x36, 0x3E, +0x90, 0xA1, 0xD5, 0x12, 0x97, 0x97, 0xA3, 0xA3, 0xA3, 0x74, 0x05, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0x90, 0xA0, 0xC1, 0xE0, 0x30, 0xE0, 0x5D, 0x90, 0xA0, 0xC3, 0xE0, 0x70, 0x2A, 0x7D, 0x16, +0x7F, 0x6F, 0x31, 0x22, 0x91, 0x22, 0x51, 0x4C, 0x54, 0x07, 0x75, 0xF0, 0x0E, 0x11, 0xC6, 0x51, +0x4C, 0x54, 0x07, 0x12, 0xA4, 0xFC, 0xE0, 0x44, 0x01, 0x12, 0xA9, 0x18, 0xA3, 0x74, 0x03, 0x11, +0x2C, 0x90, 0xA0, 0xC3, 0x74, 0x01, 0xF0, 0x22, 0x90, 0xA0, 0xC3, 0xE0, 0x64, 0x01, 0x70, 0x23, +0x90, 0xA0, 0xC1, 0xE0, 0x12, 0xA4, 0xF7, 0xE0, 0x30, 0xE0, 0x18, 0x75, 0xF0, 0x0E, 0xEF, 0x11, +0xC6, 0xE4, 0x90, 0xA1, 0xD9, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, +0x01, 0x01, 0x34, 0x31, 0x2D, 0x22, 0x90, 0xA0, 0xD0, 0x12, 0x45, 0xA9, 0xE0, 0xFF, 0x7E, 0x00, +0x7D, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xDB, 0xEE, 0xF0, 0xA3, 0xEF, +0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1C, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, +0xE0, 0xF0, 0x7D, 0x13, 0x91, 0x1E, 0xBF, 0x01, 0x02, 0x91, 0xFF, 0x90, 0xA1, 0xE0, 0xE0, 0xFF, +0x7D, 0x15, 0x31, 0x22, 0x80, 0x02, 0x91, 0xFF, 0xF1, 0x09, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0x90, 0xA0, 0xD0, 0x12, 0x45, 0xA9, 0xE0, 0xFF, 0x7E, 0x00, 0xE4, 0xFD, 0x11, 0xD2, 0xE4, +0xFD, 0xFF, 0x90, 0x05, 0x22, 0xEF, 0xF0, 0x90, 0x9E, 0x96, 0xED, 0xF0, 0x22, 0x90, 0xA0, 0xC1, +0xE0, 0xFF, 0xC3, 0x13, 0xFE, 0xEF, 0x54, 0xF1, 0xFF, 0xEE, 0x04, 0x54, 0x07, 0x25, 0xE0, 0x4F, +0xF0, 0xA3, 0xE0, 0xFF, 0x12, 0xAC, 0x6F, 0xB5, 0x07, 0x04, 0xEE, 0x54, 0xF1, 0xF0, 0x11, 0x05, +0xE4, 0x90, 0xA0, 0xC3, 0xF0, 0x91, 0x22, 0x12, 0xAC, 0x6F, 0x12, 0xAB, 0xD9, 0xE0, 0xFA, 0x75, +0xF0, 0x0E, 0xED, 0xF1, 0xB7, 0xFC, 0x54, 0x03, 0xFD, 0xEC, 0x13, 0x13, 0x54, 0x07, 0xFB, 0xEE, +0x12, 0xAC, 0xF1, 0xAF, 0x02, 0x12, 0xA6, 0x91, 0x51, 0x4C, 0x54, 0x07, 0x75, 0xF0, 0x0E, 0xF1, +0xB7, 0x12, 0xAC, 0x65, 0xFD, 0x51, 0x53, 0x51, 0x4C, 0x54, 0x07, 0xFF, 0x75, 0xF0, 0x0E, 0x90, +0xA0, 0xCF, 0x12, 0x45, 0xA9, 0xE0, 0x04, 0xF0, 0x75, 0xF0, 0x0E, 0xEF, 0x31, 0x11, 0x51, 0x4C, +0x54, 0x07, 0xFD, 0xE4, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x0C, 0xEF, +0xF0, 0xA3, 0xED, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0xA2, 0x0E, 0xE0, 0xFF, 0xC3, 0x94, 0x02, 0x40, +0x02, 0x41, 0x47, 0x90, 0xA2, 0x0D, 0xE0, 0xFE, 0x12, 0xA8, 0x09, 0x75, 0xF0, 0x03, 0xEF, 0x12, +0xAC, 0x02, 0xE0, 0x90, 0xA2, 0x0F, 0xF0, 0x90, 0xA2, 0x0C, 0xE0, 0x60, 0x24, 0x90, 0xA2, 0x0F, +0xE0, 0xFF, 0x75, 0xF0, 0x0E, 0xEE, 0x12, 0xA7, 0x8B, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xA2, 0x0E, +0xE0, 0xD0, 0x82, 0xD0, 0x83, 0x12, 0x78, 0xEE, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0x80, +0x20, 0x12, 0xAC, 0x79, 0x75, 0xF0, 0x0E, 0x12, 0xA7, 0x8B, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xA2, +0x0E, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0x12, 0x78, 0xEE, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, +0x5F, 0x90, 0xA2, 0x0F, 0xF0, 0x12, 0xAC, 0x79, 0x12, 0xA8, 0x09, 0xC0, 0x83, 0xC0, 0x82, 0x90, +0xA2, 0x0E, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0x75, 0xF0, 0x03, 0x12, 0xAC, 0x02, 0xEF, 0xF0, 0x90, +0xA2, 0x0E, 0xE0, 0x04, 0xF0, 0x21, 0xB7, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA0, 0xC1, 0xE0, +0xC3, 0x13, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x36, 0xED, 0xF0, 0xEF, +0x14, 0x60, 0x02, 0x61, 0x10, 0x90, 0x06, 0x03, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0xA2, 0x36, 0xE0, +0xC4, 0x33, 0x54, 0xE0, 0xFF, 0x90, 0x04, 0x42, 0xE0, 0x54, 0x9F, 0x4F, 0xFF, 0xF0, 0x90, 0xA1, +0x88, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0xA1, 0x8C, 0x12, 0x08, 0x79, 0x00, 0x00, +0x00, 0x01, 0x71, 0xD6, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0xA1, 0x8C, 0x12, 0x08, +0x79, 0x00, 0x00, 0x00, 0x01, 0x7F, 0x00, 0x7E, 0x09, 0x71, 0xDA, 0x12, 0x08, 0x79, 0x00, 0x00, +0x00, 0x10, 0x12, 0xAB, 0x52, 0x78, 0x01, 0x12, 0x08, 0x47, 0x78, 0x04, 0xF1, 0xC7, 0x7F, 0x00, +0x7E, 0x0A, 0x71, 0xDA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x12, 0xAB, 0x52, 0x78, 0x0A, +0xF1, 0xC7, 0x7F, 0x00, 0x7E, 0x0D, 0x71, 0xDA, 0x12, 0x08, 0x79, 0x0C, 0x00, 0x00, 0x00, 0x12, +0xAB, 0x52, 0x78, 0x1A, 0xF1, 0xC7, 0x7F, 0x18, 0x71, 0xD8, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, +0x00, 0x90, 0xA1, 0x8C, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xDA, 0x12, 0x08, 0x79, +0x00, 0x00, 0x0C, 0x00, 0x90, 0xA1, 0x7A, 0x12, 0x08, 0x79, 0x00, 0x00, 0x04, 0x00, 0x80, 0x58, +0x90, 0x06, 0x03, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xA1, 0x88, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, +0x01, 0x90, 0xA1, 0x8C, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x71, 0xD6, 0x12, 0x08, 0x79, +0x00, 0x00, 0x00, 0x01, 0x90, 0xA1, 0x8C, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, +0x7E, 0x09, 0x71, 0xDA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0xA1, 0x8C, 0x12, 0x08, +0x79, 0x00, 0x00, 0x0C, 0x00, 0xF1, 0xDA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0xA1, +0x7A, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x7D, 0x18, 0x7C, 0x00, 0xE4, 0xFF, 0x12, 0xA6, +0x19, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0x86, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x37, 0x4E, 0x90, 0xA1, 0x90, 0x12, 0x08, 0x6D, 0x90, 0xA1, +0x88, 0x12, 0x45, 0x71, 0x12, 0x08, 0x3A, 0x90, 0xA1, 0x90, 0xF1, 0xF0, 0xC0, 0x04, 0xC0, 0x05, +0xC0, 0x06, 0xC0, 0x07, 0x90, 0xA1, 0x88, 0x12, 0x45, 0x71, 0x90, 0xA1, 0x8C, 0xF1, 0xF0, 0xD0, +0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x45, 0x53, 0x90, 0xA1, 0x94, 0x12, 0x08, 0x6D, +0x90, 0xA1, 0x94, 0x12, 0x47, 0xCE, 0x90, 0xA1, 0x86, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x38, +0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x00, 0x7E, 0x08, 0x71, 0x76, 0x90, 0xA1, 0x88, 0x22, +0x8F, 0x54, 0x7D, 0x17, 0x91, 0x1E, 0x75, 0xF0, 0x0E, 0xE5, 0x54, 0x12, 0xAB, 0xDD, 0xE0, 0xFC, +0xF1, 0xB2, 0xFE, 0x54, 0x03, 0xFD, 0xEE, 0x13, 0x13, 0x54, 0x07, 0xFB, 0x90, 0xA0, 0xC1, 0xE0, +0xFE, 0x12, 0xAC, 0xF1, 0xAF, 0x04, 0x12, 0xA6, 0x91, 0xF1, 0xB2, 0x12, 0xAC, 0x65, 0xFD, 0x51, +0x53, 0x75, 0xF0, 0x0E, 0xE5, 0x54, 0x31, 0x11, 0xAD, 0x54, 0xE4, 0xFF, 0x21, 0xA5, 0x7F, 0xFF, +0x31, 0x22, 0xE4, 0x90, 0xA2, 0x2C, 0xF0, 0xA3, 0xF0, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x0F, 0xA3, +0xE0, 0x70, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0xA3, 0xE0, 0x70, 0x03, 0x7F, 0x01, 0x22, 0xF1, 0xD0, +0x30, 0xE0, 0x15, 0xD3, 0x90, 0xA2, 0x2D, 0xE0, 0x94, 0x03, 0x90, 0xA2, 0x2C, 0xE0, 0x94, 0x00, +0x40, 0x02, 0x80, 0x13, 0x7F, 0x01, 0x80, 0x1B, 0xD3, 0x90, 0xA2, 0x2D, 0xE0, 0x94, 0xE8, 0x90, +0xA2, 0x2C, 0xE0, 0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x20, 0xF0, 0x7F, 0x00, +0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0x90, 0xA2, 0x2C, 0x12, 0x96, 0x39, 0x80, 0xA9, +0x90, 0xA0, 0x66, 0xE0, 0x44, 0x02, 0xF0, 0x7D, 0x08, 0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0x90, 0xA1, 0xE6, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x9E, 0x94, 0xE0, 0x04, 0xF0, +0x90, 0x04, 0x1D, 0xE0, 0x60, 0x33, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, 0xEA, 0xF0, 0x7D, 0x26, +0x91, 0x1E, 0xEF, 0x64, 0x01, 0x70, 0x07, 0xD1, 0xB9, 0x20, 0xE0, 0x0F, 0x80, 0x0A, 0xF1, 0xD0, +0x30, 0xE0, 0x08, 0xD1, 0xB9, 0x20, 0xE0, 0x03, 0x12, 0xA9, 0xC1, 0x90, 0xA1, 0xEA, 0xE0, 0xFF, +0x7D, 0x27, 0x31, 0x22, 0x12, 0xAA, 0x45, 0x80, 0x0B, 0x12, 0xAA, 0x45, 0xD1, 0xB9, 0x20, 0xE0, +0x03, 0x12, 0xA9, 0xC1, 0x90, 0xA0, 0x5F, 0xE0, 0x30, 0xE0, 0x0B, 0xF1, 0xD0, 0x30, 0xE0, 0x06, +0xF1, 0xF6, 0x7D, 0x28, 0x31, 0x22, 0xF1, 0x09, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, +0xA1, 0xDB, 0xA3, 0xE0, 0xFF, 0x7B, 0x08, 0x7D, 0x01, 0xB1, 0x59, 0x90, 0xA1, 0xDE, 0xEE, 0xF0, +0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0xA1, 0xDD, 0xE0, 0xFF, 0xF1, 0xA6, 0x54, 0x3F, 0xF0, 0xEF, +0x60, 0x2C, 0xF1, 0xE4, 0x44, 0x10, 0xF0, 0xF1, 0xA6, 0x44, 0x80, 0xF0, 0x12, 0x9B, 0xBB, 0x30, +0xE0, 0x26, 0x12, 0x86, 0xCA, 0x50, 0x0E, 0xEF, 0x25, 0xE0, 0x25, 0xE0, 0xFF, 0x74, 0x2B, 0x2D, +0xF1, 0x92, 0xEF, 0xF0, 0x22, 0x74, 0x2B, 0x2D, 0xF1, 0x92, 0x74, 0x7F, 0xF0, 0x22, 0xF1, 0xE4, +0x54, 0xEF, 0xF0, 0xF1, 0xA6, 0x44, 0x40, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0xA2, 0x21, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0xA2, 0x20, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, +0x12, 0xAA, 0xF9, 0x7C, 0x00, 0xAD, 0x07, 0x90, 0xA2, 0x20, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, +0xA2, 0x21, 0xE0, 0x60, 0x06, 0x12, 0xAC, 0x32, 0x44, 0x80, 0xF0, 0xAF, 0x05, 0x74, 0x20, 0x2F, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0xF0, 0x12, 0xAC, 0x32, 0x54, 0xC0, +0xF0, 0xAF, 0x05, 0xF1, 0x9B, 0xE0, 0x54, 0x01, 0xFE, 0x90, 0xA2, 0x22, 0xE0, 0x25, 0xE0, 0x25, +0xE0, 0xFB, 0xEE, 0x44, 0x02, 0x4B, 0xFE, 0xF1, 0x9B, 0xEE, 0xF0, 0x74, 0x11, 0x2F, 0x12, 0xAA, +0x3D, 0x74, 0xFF, 0xF0, 0x74, 0x29, 0x2F, 0xF1, 0xE7, 0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x10, 0xEF, +0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1F, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA2, 0x13, 0xF0, 0x7D, +0x29, 0x91, 0x1E, 0xBF, 0x01, 0x05, 0x12, 0xAB, 0x1B, 0xB1, 0x1A, 0x90, 0xA2, 0x13, 0xE0, 0xFF, +0x7D, 0x2A, 0x31, 0x22, 0x80, 0x05, 0x12, 0xAB, 0x1B, 0xB1, 0x1A, 0xF1, 0x09, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xEB, 0xEE, 0xF0, 0xA3, 0xEF, +0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1D, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, 0xEF, 0xF0, 0x7D, +0x36, 0x91, 0x1E, 0xBF, 0x01, 0x03, 0x12, 0xAA, 0xB0, 0x90, 0xA1, 0xEF, 0xE0, 0xFF, 0x7D, 0x37, +0x31, 0x22, 0x80, 0x03, 0x12, 0xAA, 0xB0, 0xF1, 0xF6, 0x7D, 0x38, 0x31, 0x22, 0xF1, 0x09, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA1, 0x2B, 0xEF, 0xF1, 0xBF, 0x12, 0xAD, 0x19, 0x54, 0x1F, 0x20, +0xE0, 0x0D, 0x90, 0xA1, 0x2C, 0xE0, 0xB4, 0x01, 0x06, 0x7D, 0x36, 0x7F, 0x6F, 0x31, 0x22, 0x90, +0xA1, 0x2B, 0xE0, 0x70, 0x0B, 0x90, 0xA1, 0x2D, 0xE0, 0xFF, 0x7D, 0x05, 0x91, 0x8B, 0x80, 0x26, +0x90, 0xA1, 0x2B, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0xA1, 0x2D, 0xE0, 0xFF, 0xB1, 0xD5, 0x80, 0x16, +0x90, 0xA1, 0x2B, 0xE0, 0xB4, 0x02, 0x0F, 0xA3, 0xE0, 0xB4, 0x01, 0x0A, 0x90, 0xA0, 0xBB, 0xE0, +0xFE, 0xA3, 0xE0, 0xFF, 0xD1, 0x12, 0x12, 0xAD, 0x19, 0x54, 0x1F, 0x20, 0xE0, 0x0A, 0x90, 0xA1, +0x2C, 0xE0, 0x70, 0x04, 0xFD, 0xFF, 0x31, 0x22, 0x22, 0x90, 0x9E, 0x9A, 0xE0, 0xFF, 0x90, 0xA1, +0xE7, 0xE0, 0xFB, 0x7D, 0x01, 0xB1, 0x59, 0x90, 0xA1, 0xE8, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, +0xFD, 0x90, 0xA1, 0xE6, 0xE0, 0xFF, 0xB1, 0x1A, 0x90, 0xA0, 0xC1, 0xE0, 0x22, 0x90, 0xA1, 0x2C, +0xEF, 0xF1, 0xBF, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1E, 0x90, 0x05, 0x22, 0xE0, 0x90, 0xA1, 0x31, +0xF0, 0x7D, 0x01, 0x91, 0x1E, 0xEF, 0x64, 0x01, 0x70, 0x02, 0xF1, 0x10, 0x90, 0xA1, 0x31, 0xE0, +0xFF, 0x7D, 0x02, 0x31, 0x22, 0x80, 0x02, 0xF1, 0x10, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x22, +0x90, 0x9E, 0x9C, 0xE0, 0xFF, 0x7B, 0x08, 0x7D, 0x01, 0xB1, 0x59, 0x90, 0xA1, 0x2F, 0xEE, 0xF0, +0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0xA1, 0x2C, 0xE0, 0xFF, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, +0xA1, 0x36, 0xF0, 0x90, 0xA1, 0x33, 0xEC, 0xF1, 0xBF, 0x90, 0xA1, 0x33, 0xE0, 0xFC, 0xA3, 0xE0, +0xFD, 0xB1, 0x1A, 0x90, 0xA1, 0x33, 0xA3, 0xE0, 0xFF, 0xFD, 0x24, 0x0D, 0x12, 0xAA, 0x35, 0xE0, +0x44, 0x80, 0xF0, 0x74, 0x0D, 0x2D, 0x12, 0xAA, 0x35, 0xE0, 0x54, 0xEF, 0xF1, 0x9A, 0xE0, 0x44, +0x02, 0xF1, 0x9A, 0xE0, 0x54, 0x03, 0xF0, 0x90, 0xA1, 0x35, 0xE0, 0xFF, 0x90, 0xA1, 0x33, 0xA3, +0xE0, 0xFE, 0x24, 0x2A, 0x12, 0xAA, 0xEF, 0x90, 0xA1, 0x36, 0xE0, 0xFF, 0xF1, 0x8F, 0xEF, 0xF0, +0x74, 0x2C, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x24, 0x02, 0xF0, 0x22, 0x74, +0x2B, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF0, 0x74, 0x12, 0x2F, 0xF5, 0x82, +0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x74, 0x09, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, +0xE0, 0x22, 0x75, 0xF0, 0x0E, 0xE5, 0x54, 0x90, 0xA0, 0xC5, 0x12, 0x45, 0xA9, 0xE0, 0x22, 0xF0, +0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x22, 0x12, 0x08, 0x5A, 0x90, 0xA1, 0x8C, 0x02, 0x08, 0x6D, +0x90, 0xA0, 0x63, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22, 0x7F, 0x84, 0x7E, 0x08, 0x71, 0x76, +0x90, 0xA1, 0x76, 0x22, 0x74, 0x29, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, +0x12, 0x45, 0x8D, 0x02, 0x45, 0x46, 0x90, 0x05, 0x22, 0xE0, 0x54, 0x6F, 0xFF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x7E, 0xE8, 0x20, 0xE6, 0x02, 0x01, 0xDB, 0x90, 0x00, 0x8C, +0xE0, 0xF5, 0x6E, 0x7F, 0x8D, 0x12, 0x47, 0xAF, 0x90, 0x00, 0x8E, 0xE0, 0xF5, 0x6F, 0xEF, 0x24, +0xFC, 0x60, 0x0D, 0x24, 0x03, 0x60, 0x02, 0x01, 0xD2, 0xAF, 0x6E, 0x12, 0x7E, 0x96, 0x01, 0xD2, +0x74, 0x11, 0x25, 0x6E, 0x12, 0x76, 0x3C, 0xE0, 0xFB, 0xE4, 0xFD, 0x31, 0x0A, 0x31, 0x19, 0x13, +0x13, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0x31, 0x0A, 0x31, 0x19, 0xD1, 0xE5, 0xFB, 0x0D, 0xE4, 0x31, +0x0A, 0x31, 0x19, 0xC4, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0x31, 0x0A, 0xF1, 0xEF, 0xE0, 0xFB, 0xE4, +0xFD, 0x0F, 0x31, 0x0B, 0x90, 0x96, 0x12, 0x11, 0xE0, 0x75, 0xF0, 0x04, 0xE5, 0x6E, 0xD1, 0x3C, +0xC4, 0x13, 0x54, 0x01, 0xFB, 0x0D, 0x7F, 0x01, 0x31, 0x0B, 0xD1, 0x3C, 0x54, 0x1F, 0xFB, 0x0D, +0x11, 0xE6, 0x75, 0xF0, 0x08, 0xE5, 0x6E, 0x90, 0x89, 0x00, 0xD1, 0xF7, 0x75, 0xF0, 0x08, 0xE5, +0x6E, 0x90, 0x89, 0x01, 0x11, 0xE0, 0x75, 0xF0, 0x08, 0xE5, 0x6E, 0x90, 0x89, 0x02, 0x11, 0xE0, +0x75, 0xF0, 0x08, 0xE5, 0x6E, 0x90, 0x89, 0x03, 0x11, 0xE0, 0x75, 0xF0, 0x08, 0xE5, 0x6E, 0x90, +0x89, 0x04, 0xD1, 0xF7, 0x75, 0xF0, 0x08, 0xE5, 0x6E, 0x90, 0x89, 0x05, 0x11, 0xE0, 0x75, 0xF0, +0x08, 0xE5, 0x6E, 0x90, 0x89, 0x06, 0x11, 0xE0, 0x75, 0xF0, 0x08, 0xE5, 0x6E, 0x90, 0x89, 0x07, +0x11, 0xE0, 0x12, 0x7E, 0xE8, 0x30, 0xE0, 0x03, 0x12, 0x7F, 0x58, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x12, 0x45, 0xA9, 0xE0, 0xFB, 0x0D, 0xEF, 0x70, 0x04, 0x74, 0xF0, 0x80, 0x16, 0xEF, 0xB4, 0x01, +0x04, 0x74, 0xF4, 0x80, 0x0E, 0xEF, 0xB4, 0x02, 0x04, 0x74, 0xF8, 0x80, 0x06, 0xEF, 0xB4, 0x03, +0x08, 0x74, 0xFC, 0x2D, 0x12, 0xA1, 0x89, 0xEB, 0xF0, 0x22, 0xFF, 0x11, 0xE6, 0x75, 0xF0, 0x04, +0xE5, 0x6E, 0x22, 0xFF, 0x75, 0xF0, 0x04, 0xE5, 0x51, 0x90, 0x96, 0x14, 0x12, 0x45, 0xA9, 0xE0, +0x22, 0x12, 0x06, 0x89, 0x54, 0x7F, 0xF5, 0x51, 0x12, 0x6A, 0x87, 0xFF, 0x54, 0x1F, 0xF5, 0x53, +0xEF, 0x54, 0x80, 0xD1, 0xE5, 0xF5, 0x52, 0xD1, 0xDE, 0xFF, 0x54, 0x03, 0xF5, 0x54, 0xEF, 0x54, +0x30, 0xC4, 0x54, 0x0F, 0xF5, 0x57, 0xD1, 0xDE, 0xFF, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03, +0xF5, 0x55, 0xEF, 0x54, 0x80, 0xD1, 0xE5, 0xF5, 0x56, 0xD1, 0xDE, 0xFF, 0x54, 0x08, 0x13, 0x13, +0x13, 0x54, 0x1F, 0xF5, 0x59, 0xEF, 0x54, 0x04, 0x13, 0x13, 0x54, 0x3F, 0xF5, 0x5A, 0xE5, 0x56, +0x12, 0xAC, 0xB3, 0x31, 0x13, 0x54, 0x7F, 0x4F, 0xF0, 0xE5, 0x55, 0x12, 0x61, 0xC8, 0x31, 0x13, +0x54, 0xBF, 0x4F, 0xF0, 0xE5, 0x59, 0x70, 0x74, 0xE5, 0x53, 0x54, 0x1F, 0xD1, 0x36, 0x54, 0xE0, +0x4F, 0xF0, 0xE5, 0x54, 0x54, 0x03, 0x31, 0x13, 0x54, 0xFC, 0x4F, 0xF0, 0xEF, 0x25, 0xE0, 0x25, +0xE0, 0x31, 0x13, 0x54, 0xF3, 0x4F, 0xF0, 0xE5, 0x52, 0x54, 0x01, 0xC4, 0x33, 0x54, 0xE0, 0xD1, +0x36, 0x54, 0xDF, 0x4F, 0xF0, 0xE5, 0x57, 0x54, 0x03, 0xC4, 0x54, 0xF0, 0x31, 0x13, 0x54, 0xCF, +0x4F, 0xD1, 0x54, 0xE0, 0x54, 0xFB, 0xD1, 0x54, 0xE0, 0xFF, 0xE5, 0x5A, 0x25, 0xE0, 0x25, 0xE0, +0xFE, 0xEF, 0x4E, 0xF0, 0xE4, 0xF5, 0x58, 0x85, 0x58, 0x82, 0x75, 0x83, 0x00, 0xA3, 0xA3, 0xA3, +0x12, 0x06, 0xA2, 0xFF, 0x75, 0xF0, 0x08, 0xE5, 0x51, 0xD1, 0x4B, 0x25, 0x58, 0xB1, 0x36, 0xEF, +0xF0, 0x05, 0x58, 0xE5, 0x58, 0xB4, 0x04, 0xDF, 0xAF, 0x51, 0x71, 0x22, 0x22, 0x90, 0xA0, 0xFE, +0x12, 0x45, 0xBE, 0x90, 0xA0, 0xFD, 0xEF, 0xF0, 0x12, 0x45, 0xC7, 0x52, 0x6F, 0x00, 0x52, 0x74, +0x01, 0x52, 0x79, 0x02, 0x52, 0x7E, 0x10, 0x52, 0x83, 0x11, 0x52, 0x87, 0x12, 0x52, 0x8C, 0x14, +0x52, 0x91, 0x20, 0x52, 0x96, 0x21, 0x52, 0x9B, 0x23, 0x52, 0xA0, 0x24, 0x52, 0xA5, 0x25, 0x52, +0xAA, 0x27, 0x52, 0xAF, 0x28, 0x52, 0xB4, 0x40, 0x52, 0xB8, 0x42, 0x52, 0xBC, 0x60, 0x52, 0xC1, +0x61, 0x52, 0xC6, 0x62, 0x52, 0xCB, 0x63, 0x52, 0xD0, 0x64, 0x52, 0xD5, 0x65, 0x52, 0xDA, 0x66, +0x52, 0xDF, 0x67, 0x52, 0xE4, 0x68, 0x52, 0xE9, 0x69, 0x52, 0xEE, 0x6B, 0x52, 0xF3, 0x6C, 0x52, +0xF8, 0x6D, 0x52, 0xFD, 0x6E, 0x53, 0x02, 0x6F, 0x53, 0x07, 0x70, 0x00, 0x00, 0x53, 0x0C, 0x71, +0x1C, 0x02, 0x6D, 0x37, 0x71, 0x1C, 0x02, 0x7F, 0x6D, 0x71, 0x1C, 0x02, 0x9C, 0x55, 0x71, 0x1C, +0x02, 0x9C, 0x93, 0x71, 0x1C, 0xE1, 0x0F, 0x71, 0x1C, 0x02, 0x9A, 0x35, 0x71, 0x1C, 0x02, 0x9C, +0xB6, 0x71, 0x1C, 0x02, 0x69, 0x41, 0x71, 0x1C, 0x02, 0x9C, 0xC5, 0x71, 0x1C, 0x02, 0x9D, 0x04, +0x71, 0x1C, 0x02, 0x5C, 0xDE, 0x71, 0x1C, 0x02, 0x9D, 0x0C, 0x71, 0x1C, 0x02, 0x89, 0x61, 0x71, +0x1C, 0x02, 0x9D, 0x4F, 0x71, 0x1C, 0x21, 0x21, 0x71, 0x1C, 0xC1, 0x61, 0x71, 0x1C, 0x02, 0x6A, +0x8D, 0x71, 0x1C, 0x02, 0x93, 0x0A, 0x71, 0x1C, 0x02, 0x6F, 0xCB, 0x71, 0x1C, 0x02, 0x9D, 0xFC, +0x71, 0x1C, 0x02, 0x9E, 0x29, 0x71, 0x1C, 0x02, 0x9E, 0x87, 0x71, 0x1C, 0x02, 0x6E, 0x45, 0x71, +0x1C, 0x02, 0x98, 0x97, 0x71, 0x1C, 0x02, 0x9E, 0x10, 0x71, 0x1C, 0x02, 0x6D, 0x70, 0x71, 0x1C, +0x02, 0x9E, 0x95, 0x71, 0x1C, 0x02, 0x6F, 0x00, 0x71, 0x1C, 0x02, 0x92, 0xBB, 0x71, 0x1C, 0x02, +0x9F, 0x80, 0x71, 0x1C, 0x02, 0x9D, 0x78, 0x71, 0x1C, 0x02, 0x9F, 0xB2, 0x90, 0x01, 0xC0, 0xE0, +0x44, 0x01, 0xF0, 0x90, 0xA0, 0xFD, 0xE0, 0x90, 0x01, 0xC2, 0xF0, 0x22, 0x90, 0xA0, 0xFE, 0x02, +0x45, 0xB5, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x04, 0xEF, 0xF0, 0x75, 0xF0, +0x04, 0xD1, 0x3C, 0x54, 0x1F, 0xFB, 0x60, 0x12, 0x64, 0x02, 0x60, 0x0E, 0xEB, 0x64, 0x04, 0x60, +0x09, 0xEB, 0x64, 0x09, 0x60, 0x04, 0xEB, 0xB4, 0x0C, 0x0A, 0x12, 0xAC, 0x0E, 0xF5, 0x83, 0x74, +0x02, 0xF0, 0x80, 0x08, 0x12, 0xAC, 0x0E, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0xE4, 0xF5, 0x6B, 0x90, +0xA2, 0x04, 0xE0, 0xFD, 0xD1, 0x48, 0x25, 0x6B, 0xB1, 0x36, 0xE0, 0xFE, 0xEB, 0x75, 0xF0, 0x07, +0xA4, 0x24, 0x56, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE5, 0x82, 0x25, 0x6B, 0xB1, 0x36, +0xE4, 0x93, 0xFC, 0xEE, 0x5C, 0x90, 0xA2, 0x07, 0xF0, 0x75, 0xF0, 0x04, 0xED, 0x31, 0x19, 0x54, +0x03, 0xFF, 0xBF, 0x02, 0x0B, 0xE5, 0x6B, 0x70, 0x07, 0x90, 0xA2, 0x07, 0xE0, 0x54, 0xF0, 0xF0, +0x90, 0xA2, 0x07, 0xE0, 0xFF, 0xD1, 0x44, 0x25, 0x6B, 0xB1, 0x36, 0xEF, 0xF0, 0x05, 0x6B, 0xE5, +0x6B, 0x64, 0x07, 0x70, 0xAA, 0x90, 0xA2, 0x04, 0xE0, 0x75, 0xF0, 0x04, 0x31, 0x19, 0xFF, 0xC4, +0x54, 0x03, 0xFD, 0xE4, 0x90, 0xA2, 0x05, 0xF0, 0x75, 0x6C, 0x06, 0xE5, 0x6C, 0xB4, 0x06, 0x07, +0xB1, 0x25, 0xE0, 0x54, 0x0F, 0x80, 0x07, 0xD1, 0x44, 0x25, 0x6C, 0xB1, 0x36, 0xE0, 0x90, 0xA2, +0x06, 0xF0, 0x90, 0xA2, 0x06, 0xE0, 0x60, 0x33, 0x75, 0x6B, 0x07, 0x12, 0xAC, 0xF9, 0x80, 0x05, +0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x12, 0xAC, 0xC5, 0x60, 0x16, 0x12, 0xAC, 0xBC, 0x90, +0xA2, 0x05, 0xF0, 0xED, 0x60, 0x22, 0xE0, 0xD3, 0x94, 0x0B, 0x40, 0x1C, 0xE0, 0x24, 0x20, 0xF0, +0x80, 0x16, 0x15, 0x6B, 0xE5, 0x6B, 0xC3, 0x94, 0x00, 0x50, 0xD0, 0xE5, 0x6C, 0x60, 0x09, 0x15, +0x6C, 0xE5, 0x6C, 0xC3, 0x94, 0x00, 0x50, 0xA3, 0xE4, 0xFC, 0xF5, 0x6C, 0xE5, 0x6C, 0xB4, 0x06, +0x07, 0xB1, 0x25, 0xE0, 0x54, 0x0F, 0x80, 0x07, 0xD1, 0x44, 0x25, 0x6C, 0xB1, 0x36, 0xE0, 0x90, +0xA2, 0x06, 0xF0, 0x90, 0xA2, 0x06, 0xE0, 0x60, 0x2E, 0xE4, 0xF5, 0x6B, 0x12, 0xAC, 0xF9, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x12, 0xAC, 0xC5, 0x60, 0x13, 0x12, 0xAC, 0xBC, +0xFC, 0xED, 0x60, 0x1B, 0xEC, 0xD3, 0x94, 0x0B, 0x40, 0x15, 0x74, 0x20, 0x2C, 0xFC, 0x80, 0x0F, +0x05, 0x6B, 0xE5, 0x6B, 0xB4, 0x08, 0xD5, 0x05, 0x6C, 0xE5, 0x6C, 0x64, 0x07, 0x70, 0xAD, 0x90, +0xA2, 0x05, 0xE0, 0xFF, 0x90, 0xA2, 0x04, 0xE0, 0xFE, 0x75, 0xF0, 0x04, 0xF1, 0xEF, 0xEF, 0xF0, +0x75, 0xF0, 0x04, 0xEE, 0xD1, 0xF1, 0xEC, 0xF0, 0x75, 0xF0, 0x10, 0xEE, 0x12, 0x7B, 0x91, 0xE0, +0xFE, 0x54, 0x7F, 0xF5, 0x6D, 0xEE, 0x54, 0x80, 0xFE, 0xE5, 0x6D, 0xD3, 0x9F, 0x40, 0x09, 0x90, +0xA2, 0x05, 0xE0, 0x4E, 0xF5, 0x6D, 0x80, 0x0C, 0xE5, 0x6D, 0xC3, 0x9C, 0x50, 0x06, 0xAF, 0x06, +0xEC, 0x4F, 0xF5, 0x6D, 0x90, 0xA2, 0x04, 0xE0, 0xFF, 0x24, 0x91, 0x12, 0xAB, 0x85, 0xE5, 0x6D, +0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, 0x19, 0x12, 0x7B, 0xA3, 0x90, 0xA2, 0x04, 0xE0, 0xFF, 0xE4, +0xFB, 0xAD, 0x6D, 0x12, 0x77, 0x89, 0x90, 0xA2, 0x04, 0xE0, 0xFF, 0x75, 0xF0, 0x10, 0x12, 0x79, +0x4E, 0xE4, 0xF0, 0x90, 0xA2, 0x05, 0xE0, 0xFE, 0xC3, 0x94, 0x0C, 0x40, 0x08, 0x12, 0xA5, 0xA8, +0x74, 0x02, 0xF0, 0x80, 0x1B, 0xEE, 0xC3, 0x94, 0x04, 0x90, 0xA2, 0x04, 0xE0, 0x40, 0x0A, 0x24, +0x91, 0x12, 0xA5, 0xAB, 0x74, 0x01, 0xF0, 0x80, 0x07, 0x24, 0x91, 0x12, 0xA5, 0xAB, 0xE4, 0xF0, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xFF, 0x90, 0xA2, 0x04, 0xE0, 0x75, 0xF0, 0x08, 0x90, 0x89, 0x00, +0x12, 0x45, 0xA9, 0xE5, 0x82, 0x2F, 0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE4, 0xFF, +0xE4, 0xFE, 0x74, 0x91, 0x2F, 0xD1, 0x59, 0xE0, 0x54, 0xFE, 0xF0, 0x75, 0xF0, 0x10, 0xEF, 0x90, +0x81, 0x00, 0xBE, 0x03, 0x0D, 0x12, 0x45, 0xA9, 0xE5, 0x82, 0x2E, 0xB1, 0x36, 0x74, 0x80, 0xF0, +0x80, 0x0A, 0x12, 0x45, 0xA9, 0xE5, 0x82, 0x2E, 0xB1, 0x36, 0xE4, 0xF0, 0x75, 0xF0, 0x08, 0xEF, +0xD1, 0x4B, 0x2E, 0xB1, 0x36, 0xE4, 0xF0, 0x0E, 0xBE, 0x10, 0xC7, 0x0F, 0xBF, 0x80, 0xC1, 0xE4, +0x90, 0xAD, 0xE2, 0xF0, 0xFF, 0xE4, 0xFE, 0x75, 0xF0, 0x0A, 0xEF, 0x12, 0x7A, 0x8A, 0x75, 0xF0, +0x02, 0xEE, 0x12, 0x45, 0xA9, 0xE4, 0xF0, 0xA3, 0xF0, 0x0E, 0xBE, 0x05, 0xEA, 0x74, 0x91, 0x2F, +0x12, 0xAB, 0x85, 0x74, 0x13, 0xF0, 0x74, 0x11, 0x2F, 0x12, 0xAB, 0x65, 0xE4, 0xF0, 0x74, 0x01, +0x2F, 0x12, 0x76, 0x14, 0x74, 0xC0, 0xF0, 0x74, 0x11, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x9E, 0xF5, +0x83, 0xE4, 0x12, 0x7A, 0xC0, 0x12, 0xAB, 0xAA, 0xF1, 0xEA, 0x74, 0x13, 0xD1, 0xEC, 0xE4, 0xF0, +0x75, 0xF0, 0x04, 0xEF, 0xD1, 0x3C, 0x54, 0xE0, 0x44, 0x09, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, +0x19, 0x54, 0xF3, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, 0x19, 0x54, 0xFC, 0xF0, 0x75, 0xF0, 0x04, +0xEF, 0xD1, 0x3C, 0x44, 0x20, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, 0x19, 0x54, 0xCF, 0xF0, 0x75, +0xF0, 0x04, 0xEF, 0x31, 0x19, 0x44, 0x40, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x31, 0x19, 0x54, 0x7F, +0xD1, 0xEC, 0xE0, 0xFE, 0x75, 0xF0, 0x10, 0xEF, 0x12, 0x7B, 0x91, 0xEE, 0xF0, 0x74, 0x91, 0x2F, +0xD1, 0x59, 0xE4, 0xF0, 0x0F, 0xEF, 0x64, 0x80, 0x60, 0x02, 0xA1, 0x85, 0x74, 0x11, 0x2F, 0x12, +0x98, 0x8F, 0x74, 0xFF, 0xF0, 0x22, 0xFF, 0x75, 0xF0, 0x04, 0xE5, 0x51, 0x90, 0x96, 0x13, 0x12, +0x45, 0xA9, 0xE0, 0x22, 0x90, 0xA2, 0x04, 0xE0, 0x75, 0xF0, 0x08, 0x90, 0x89, 0x00, 0x12, 0x45, +0xA9, 0xE5, 0x82, 0x22, 0xF0, 0x74, 0x91, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x99, 0xF5, 0x83, +0x22, 0x12, 0x6F, 0x66, 0x12, 0x06, 0x89, 0xF5, 0x51, 0x24, 0x91, 0xD1, 0x59, 0xE0, 0x54, 0x9C, +0xD1, 0x54, 0xC0, 0x83, 0xC0, 0x82, 0xF1, 0x01, 0x54, 0x01, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0, +0x83, 0xD1, 0x54, 0xC0, 0x83, 0xC0, 0x82, 0xF1, 0x01, 0x54, 0x02, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, +0xD0, 0x83, 0xD1, 0x54, 0xC0, 0x83, 0xC0, 0x82, 0xF1, 0x01, 0x54, 0x40, 0xFE, 0xEF, 0x4E, 0xD0, +0x82, 0xD0, 0x83, 0xD1, 0x54, 0xC0, 0x83, 0xC0, 0x82, 0xF1, 0x01, 0x54, 0x20, 0xFE, 0xEF, 0x4E, +0xD0, 0x82, 0xD0, 0x83, 0xF0, 0xE5, 0x51, 0xC3, 0x94, 0x80, 0x50, 0x08, 0xD1, 0xDE, 0xFF, 0x12, +0x76, 0x38, 0xEF, 0xF0, 0xD1, 0x55, 0xE0, 0x30, 0xE5, 0x11, 0x31, 0x14, 0x13, 0x13, 0x54, 0x03, +0xFB, 0x12, 0x76, 0x38, 0xE0, 0xFD, 0xAF, 0x51, 0x12, 0xA5, 0xB3, 0x22, 0x4F, 0xF0, 0x90, 0x00, +0x02, 0x02, 0x06, 0xA2, 0xE0, 0xC4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x22, 0xF0, 0x75, 0xF0, 0x04, +0xEF, 0x90, 0x96, 0x12, 0x02, 0x45, 0xA9, 0x12, 0x45, 0xA9, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x01, +0xE6, 0xE0, 0xFF, 0x90, 0xA1, 0x01, 0x12, 0x45, 0xB5, 0x90, 0x00, 0x03, 0x02, 0x06, 0xA2, 0x12, +0x7F, 0xC2, 0x12, 0x06, 0x89, 0xC4, 0x54, 0x0F, 0xFF, 0xBF, 0x0F, 0x18, 0x90, 0xA0, 0xC1, 0xE0, +0x54, 0xFE, 0xF0, 0x12, 0x88, 0xA9, 0xF1, 0xE3, 0x12, 0x06, 0x89, 0x54, 0x0F, 0xFF, 0x12, 0x4B, +0xE0, 0x02, 0xA7, 0x11, 0xF1, 0xE3, 0x12, 0x6A, 0x87, 0xFF, 0x12, 0x06, 0x89, 0xFE, 0x54, 0x0F, +0x12, 0xAB, 0xD9, 0xEF, 0xD1, 0xDD, 0x54, 0x03, 0xFF, 0x75, 0xF0, 0x0E, 0xED, 0x12, 0x4F, 0xB7, +0x54, 0xFC, 0xD1, 0xDC, 0x54, 0x1C, 0xFF, 0xEE, 0x54, 0x0F, 0xFE, 0x75, 0xF0, 0x0E, 0x12, 0x4F, +0xB7, 0x54, 0xE3, 0xD1, 0xDC, 0x54, 0xE0, 0xFF, 0x75, 0xF0, 0x0E, 0xEE, 0x12, 0x4F, 0xB7, 0x54, +0x1F, 0x4F, 0x12, 0x6D, 0x27, 0x12, 0xAC, 0xE9, 0xE4, 0xFB, 0x12, 0xA7, 0x9B, 0xF1, 0xE3, 0x12, +0x6A, 0x7A, 0x12, 0xAC, 0xE9, 0x7B, 0x01, 0x12, 0xA7, 0x9B, 0xF1, 0xE3, 0xF1, 0x09, 0x12, 0x9D, +0x71, 0x12, 0x06, 0x89, 0xFE, 0x54, 0x0F, 0xFD, 0x75, 0xF0, 0x0E, 0x90, 0xA0, 0xCD, 0x12, 0x45, +0xA9, 0xEF, 0xF0, 0xF1, 0x09, 0xC4, 0x13, 0x54, 0x07, 0xFF, 0x75, 0xF0, 0x0E, 0xED, 0x90, 0xA0, +0xCE, 0x12, 0x45, 0xA9, 0xEF, 0xF0, 0xEE, 0xC4, 0x54, 0x0F, 0xFF, 0x14, 0x6D, 0x70, 0x23, 0x90, +0xA0, 0xC2, 0xEF, 0xF0, 0x12, 0x6A, 0x80, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x90, 0xA0, 0xC1, +0xE0, 0x54, 0x0F, 0x4F, 0xF0, 0x54, 0xF1, 0xF0, 0x44, 0x01, 0xF0, 0x7D, 0x20, 0xE4, 0xFF, 0x12, +0x88, 0xD0, 0x22, 0xAB, 0x51, 0xAA, 0x52, 0xA9, 0x53, 0x22, 0xF0, 0x75, 0xF0, 0x04, 0xEF, 0x90, +0x96, 0x11, 0x02, 0x45, 0xA9, 0x7F, 0xF4, 0x12, 0x47, 0xAF, 0xEF, 0x20, 0xE5, 0x0E, 0x7F, 0xF4, +0x12, 0x47, 0xAF, 0xEF, 0x7F, 0x01, 0x20, 0xE4, 0x05, 0x7F, 0x02, 0x22, 0x7F, 0x03, 0x22, 0x12, +0x57, 0xF5, 0x90, 0x9E, 0x97, 0xEF, 0xF0, 0x11, 0x4E, 0x90, 0x01, 0x64, 0x74, 0x01, 0xF0, 0x90, +0x04, 0x23, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x17, 0x12, 0x47, 0xAF, 0xEF, 0x54, 0xFC, 0x44, 0x04, +0xFD, 0x7F, 0x17, 0x12, 0x46, 0xA0, 0x12, 0xAC, 0xA1, 0x44, 0x40, 0xFD, 0x7F, 0x16, 0x12, 0x46, +0xA0, 0x7F, 0x38, 0x12, 0xAD, 0x39, 0x7F, 0x38, 0x12, 0x46, 0xA0, 0x02, 0x37, 0x99, 0x11, 0x7E, +0x11, 0xAC, 0x12, 0xA1, 0x9C, 0x12, 0xA1, 0xBB, 0xE4, 0xF5, 0x0D, 0xF5, 0x0E, 0xF5, 0x0F, 0x75, +0x10, 0x80, 0xAD, 0x0D, 0x7F, 0x50, 0x12, 0x46, 0xA0, 0xAD, 0x0E, 0x7F, 0x51, 0x12, 0x46, 0xA0, +0xAD, 0x0F, 0x7F, 0x52, 0x12, 0x46, 0xA0, 0xAD, 0x10, 0x7F, 0x53, 0x02, 0x46, 0xA0, 0x90, 0x01, +0x30, 0xE4, 0x11, 0xA4, 0x90, 0x01, 0x38, 0x11, 0xA4, 0xFD, 0x7F, 0x50, 0x12, 0x46, 0xA0, 0xE4, +0xFD, 0x7F, 0x51, 0x12, 0x46, 0xA0, 0xE4, 0xFD, 0x7F, 0x52, 0x12, 0x46, 0xA0, 0xE4, 0xFD, 0x7F, +0x53, 0x02, 0x46, 0xA0, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x01, 0x34, 0x74, +0xFF, 0x11, 0xA4, 0x90, 0x01, 0x3C, 0x11, 0xA4, 0xFD, 0x7F, 0x54, 0x12, 0x46, 0xA0, 0x7D, 0xFF, +0x7F, 0x55, 0x12, 0x46, 0xA0, 0x7D, 0xFF, 0x7F, 0x56, 0x12, 0x46, 0xA0, 0x7D, 0xFF, 0x7F, 0x57, +0x02, 0x46, 0xA0, 0xEF, 0x64, 0x01, 0x70, 0x20, 0x91, 0xA7, 0x90, 0x01, 0x38, 0xE4, 0x11, 0xA4, +0x90, 0x01, 0x30, 0x11, 0xA4, 0x90, 0x01, 0x30, 0x74, 0x10, 0xF0, 0x90, 0x01, 0x39, 0x74, 0x01, +0xF0, 0x90, 0x00, 0x53, 0x74, 0x80, 0xF0, 0x22, 0x12, 0x97, 0xAD, 0x90, 0xA0, 0x5C, 0xE0, 0x90, +0x01, 0x31, 0xF0, 0x90, 0xA0, 0x5D, 0xE0, 0x90, 0x01, 0x32, 0xF0, 0x90, 0xA0, 0x5E, 0xE0, 0x90, +0x01, 0x33, 0xF0, 0x90, 0xA0, 0x57, 0xE0, 0x90, 0x01, 0x38, 0xF0, 0x90, 0xA0, 0x5A, 0xE0, 0x90, +0x01, 0x3B, 0x91, 0xC6, 0x7F, 0x01, 0x51, 0x85, 0x7E, 0x00, 0x7F, 0xA8, 0x7D, 0x00, 0x7B, 0x01, +0x7A, 0x9F, 0x79, 0xA3, 0x12, 0x08, 0xAA, 0x12, 0xAB, 0xE3, 0x12, 0x08, 0xAA, 0x90, 0x9F, 0xA6, +0x74, 0x02, 0xF0, 0x90, 0x9F, 0xAD, 0x14, 0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x90, 0x9F, +0xB3, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0x12, 0xAB, 0xBA, 0xE4, 0xFD, 0xFF, 0x51, 0x1E, 0x7D, 0x0C, +0x7F, 0x02, 0x51, 0x1E, 0x51, 0x1A, 0x90, 0x9E, 0x97, 0xE0, 0xB4, 0x01, 0x08, 0x90, 0x9F, 0xB2, +0x74, 0xDD, 0xF0, 0x80, 0x12, 0x90, 0x9E, 0x97, 0xE0, 0x90, 0x9F, 0xB2, 0xB4, 0x03, 0x05, 0x74, +0xD4, 0xF0, 0x80, 0x03, 0x74, 0x40, 0xF0, 0x7F, 0x79, 0x12, 0x47, 0xAF, 0xEF, 0x54, 0x03, 0xFF, +0xBF, 0x02, 0x0F, 0x7F, 0x28, 0x12, 0x47, 0xAF, 0xEF, 0x30, 0xE2, 0x06, 0x90, 0x9F, 0xDD, 0x74, +0x02, 0xF0, 0x12, 0x9C, 0xF1, 0x74, 0x05, 0x12, 0xAB, 0xBA, 0x90, 0xA0, 0x56, 0xE0, 0x54, 0xFE, +0xF0, 0x90, 0x01, 0x38, 0xE0, 0x90, 0xA0, 0x57, 0xF0, 0x90, 0x01, 0x39, 0xE0, 0x90, 0xA0, 0x58, +0xF0, 0x90, 0x01, 0x3A, 0xE0, 0x90, 0xA0, 0x59, 0xF0, 0x90, 0x01, 0x3B, 0xE0, 0x90, 0xA0, 0x5A, +0xF0, 0x90, 0x01, 0x30, 0xE0, 0x90, 0xA0, 0x5B, 0xF0, 0x90, 0x01, 0x31, 0xE0, 0x90, 0xA0, 0x5C, +0xF0, 0x90, 0x01, 0x32, 0xE0, 0x90, 0xA0, 0x5D, 0xF0, 0x90, 0x01, 0x33, 0xE0, 0x90, 0xA0, 0x5E, +0xF0, 0x7F, 0x01, 0x12, 0x8F, 0x8A, 0x7E, 0x00, 0x7F, 0x02, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0xA0, +0x79, 0x4F, 0x12, 0x08, 0xAA, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F, 0x12, 0xAC, 0xAA, 0x91, 0x93, +0xE4, 0x90, 0xA0, 0x51, 0xF0, 0x22, 0xE0, 0x54, 0x7F, 0xF0, 0x7D, 0x0C, 0x7F, 0x01, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x38, 0xEF, 0xF0, 0x14, 0x60, 0x15, 0x14, 0x60, 0x19, +0x24, 0x02, 0x70, 0x1A, 0xED, 0x54, 0x01, 0xFF, 0x90, 0x9F, 0xA3, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, +0x80, 0x0C, 0x90, 0x9F, 0xAA, 0xED, 0xF0, 0x80, 0x05, 0x90, 0x9F, 0xA9, 0xED, 0xF0, 0x12, 0x7E, +0xE8, 0x30, 0xE4, 0x2C, 0x90, 0xA2, 0x38, 0xE0, 0x14, 0x60, 0x07, 0x14, 0x60, 0x18, 0x24, 0x02, +0x70, 0x1E, 0x90, 0x9F, 0xA3, 0xE0, 0x12, 0xAC, 0xB3, 0xFF, 0x90, 0x9F, 0xAA, 0xE0, 0x54, 0x7F, +0x4F, 0xFD, 0x7F, 0x88, 0x80, 0x07, 0x90, 0x9F, 0xA9, 0xE0, 0xFD, 0x7F, 0x89, 0x12, 0x46, 0xA0, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA2, 0x39, 0xEF, 0xF0, 0x12, 0x64, 0xAA, 0x90, 0xA2, 0x39, +0xE0, 0x60, 0x02, 0x91, 0x93, 0x7D, 0x04, 0xD1, 0xE8, 0x74, 0x04, 0xF0, 0x22, 0x7D, 0x01, 0x7F, +0x04, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x3A, 0xED, 0xF0, 0x90, 0x9F, 0xA3, +0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x02, 0x61, 0xE3, 0xEE, 0x12, 0x56, 0xE5, +0x30, 0xE0, 0x02, 0x61, 0xE3, 0x90, 0x9F, 0xAA, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0x61, 0xE3, 0xEF, +0x70, 0x02, 0x61, 0x5D, 0x24, 0xFE, 0x70, 0x02, 0x61, 0x96, 0x24, 0xFE, 0x60, 0x47, 0x24, 0xFC, +0x70, 0x02, 0x61, 0xD1, 0x24, 0xFC, 0x60, 0x02, 0x61, 0xE3, 0xEE, 0xB4, 0x0E, 0x02, 0x91, 0x19, +0x90, 0x9F, 0xAA, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x51, 0x85, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x06, +0x02, 0x91, 0x3E, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x04, 0x0D, 0x90, 0xA2, 0x3A, 0xE0, 0xFF, 0x60, +0x04, 0xD1, 0xFD, 0x80, 0x02, 0xF1, 0x92, 0x90, 0x9F, 0xAA, 0xE0, 0x64, 0x08, 0x60, 0x02, 0x61, +0xE3, 0x91, 0x99, 0x61, 0xE3, 0x90, 0x9F, 0xAA, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x51, 0x85, 0x90, +0x9F, 0xAA, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0x3E, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x0E, 0x07, 0x71, +0xE8, 0xBF, 0x01, 0x02, 0x91, 0x19, 0x90, 0x9F, 0xAA, 0xE0, 0x64, 0x0C, 0x60, 0x02, 0x61, 0xE3, +0x71, 0xE8, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x61, 0xE3, 0x91, 0x64, 0x61, 0xE3, 0x90, 0x9F, 0xAA, +0xE0, 0xB4, 0x0E, 0x07, 0x71, 0xE8, 0xBF, 0x01, 0x02, 0x91, 0x19, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, +0x06, 0x02, 0x91, 0x3E, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x0C, 0x07, 0x71, 0xE8, 0xBF, 0x01, 0x02, +0x91, 0x64, 0x90, 0x9F, 0xAA, 0xE0, 0x64, 0x04, 0x70, 0x59, 0x12, 0xA3, 0x9E, 0xEF, 0x64, 0x01, +0x70, 0x51, 0x91, 0xA7, 0x80, 0x4D, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0xE8, 0xBF, +0x01, 0x02, 0x91, 0x19, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0x3E, 0x90, 0x9F, 0xAA, +0xE0, 0xB4, 0x0C, 0x07, 0x71, 0xE8, 0xBF, 0x01, 0x02, 0x91, 0x64, 0x90, 0x9F, 0xAA, 0xE0, 0x70, +0x04, 0x7F, 0x01, 0x51, 0x85, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x04, 0x17, 0x12, 0xA9, 0xA2, 0x80, +0x12, 0x90, 0x9F, 0xAA, 0xE0, 0xB4, 0x0C, 0x0B, 0x90, 0x9F, 0xA4, 0x12, 0x8D, 0x05, 0x30, 0xE0, +0x02, 0xD1, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA0, 0x5F, 0xE0, 0x30, 0xE0, 0x0D, 0x90, +0xA0, 0x65, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x08, 0x80, 0x1A, 0x12, 0xA3, 0x35, 0xBF, +0x01, 0x14, 0x12, 0xA9, 0x1F, 0x54, 0x1F, 0x20, 0xE0, 0x0C, 0x90, 0x9F, 0xA9, 0xE0, 0xD3, 0x94, +0x04, 0x50, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x9F, 0xA4, 0xE0, 0xC3, 0x13, 0x20, +0xE0, 0x04, 0x51, 0x1A, 0x80, 0x12, 0x12, 0xAA, 0xA5, 0xD1, 0xD4, 0x90, 0x05, 0x27, 0xE0, 0x44, +0x80, 0xF0, 0x90, 0x9F, 0xA2, 0x74, 0x04, 0xF0, 0xE4, 0xFD, 0xFF, 0x02, 0x49, 0x22, 0x90, 0x9F, +0xA4, 0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, 0x07, 0xE0, 0x44, 0x40, 0xD1, 0xD4, 0x80, 0x0F, 0x51, +0x16, 0x90, 0x05, 0x27, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x9F, 0xA2, 0x74, 0x0C, 0xF0, 0xE4, 0xFD, +0xFF, 0x02, 0x49, 0x22, 0xF1, 0x8C, 0x64, 0x01, 0x70, 0x22, 0x90, 0x9F, 0xA4, 0xE0, 0x54, 0xFD, +0xF0, 0x7D, 0x2C, 0x7F, 0x6F, 0x12, 0x49, 0x22, 0x12, 0x4C, 0x80, 0xBF, 0x01, 0x0E, 0x90, 0x9F, +0xA3, 0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E, 0xD1, 0xE8, 0x74, 0x0E, 0xF0, 0x22, 0xE4, 0xFD, 0x7F, +0x0C, 0x51, 0xA1, 0xE4, 0xFD, 0xFF, 0x02, 0x49, 0x22, 0x12, 0x64, 0xAA, 0x91, 0x93, 0x51, 0x1A, +0x90, 0x9F, 0xA2, 0x74, 0x0C, 0xF0, 0x22, 0x7D, 0x2D, 0x12, 0x4C, 0x1E, 0x90, 0x01, 0x37, 0x74, +0x02, 0xF0, 0xFD, 0x7F, 0x03, 0x91, 0xD1, 0x12, 0x63, 0x05, 0xE4, 0xFD, 0x7F, 0x01, 0x51, 0x1E, +0xE4, 0x90, 0x9F, 0xA2, 0xF0, 0x22, 0xF0, 0x7D, 0x01, 0x7F, 0x02, 0x91, 0xD1, 0x7D, 0x02, 0x7F, +0x02, 0x74, 0x15, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x30, 0x02, 0x88, 0xB6, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x7F, 0xC2, 0x90, 0x05, 0x27, 0xE0, 0xF5, 0x54, 0x12, 0x8F, +0xC9, 0x90, 0x9F, 0x9E, 0x12, 0x6F, 0x44, 0xFF, 0xF0, 0x12, 0x06, 0x89, 0x12, 0x6D, 0x2E, 0xFF, +0x90, 0x9F, 0x9E, 0x12, 0x6F, 0x7C, 0x12, 0x6F, 0xB4, 0x12, 0x6F, 0x8D, 0x90, 0x9F, 0x9E, 0x12, +0x9F, 0x77, 0x12, 0x6F, 0xB4, 0xFE, 0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0x4D, 0x90, 0x9F, 0x9E, +0xF0, 0xEE, 0xC3, 0x13, 0x20, 0xE0, 0x02, 0xA1, 0xB3, 0xE0, 0x30, 0xE0, 0x74, 0x12, 0x88, 0xCC, +0x75, 0x54, 0x21, 0x12, 0xAC, 0xD7, 0x30, 0xE0, 0x04, 0xD1, 0x60, 0x80, 0x0C, 0xE4, 0x90, 0x9F, +0x9F, 0xF0, 0xA3, 0xF0, 0x7D, 0x40, 0xFF, 0xF1, 0xAB, 0x90, 0x9F, 0x9E, 0xE0, 0xD1, 0xCD, 0x30, +0xE0, 0x03, 0x43, 0x54, 0x12, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x43, 0x54, 0x14, 0x90, +0x9F, 0x9E, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x03, 0x43, 0x54, 0x80, 0x90, 0x9F, 0x9E, +0x12, 0x4F, 0xD3, 0x20, 0xE0, 0x03, 0x43, 0x54, 0x40, 0xD1, 0x59, 0x90, 0x9F, 0xA1, 0xE0, 0x70, +0x05, 0x7F, 0x01, 0x12, 0x84, 0x59, 0x12, 0x6F, 0xA1, 0x30, 0xE0, 0x04, 0x7F, 0x04, 0x80, 0x0C, +0x12, 0x82, 0xF0, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x12, 0x84, 0x59, 0xC1, +0x22, 0xD1, 0x56, 0x90, 0x9F, 0xA1, 0xE0, 0x64, 0x04, 0x60, 0x02, 0xC1, 0x51, 0xFF, 0x12, 0x84, +0x59, 0xC1, 0x51, 0x90, 0x9F, 0x9E, 0xE0, 0x30, 0xE0, 0x70, 0x12, 0x88, 0xCC, 0x43, 0x54, 0x31, +0x12, 0xAC, 0xD7, 0x30, 0xE0, 0x04, 0xD1, 0x60, 0x80, 0x06, 0x7D, 0x40, 0xE4, 0xFF, 0xF1, 0xAB, +0x90, 0x9F, 0x9E, 0xE0, 0xD1, 0xCD, 0x30, 0xE0, 0x03, 0x43, 0x54, 0x02, 0xEF, 0xC4, 0x54, 0x0F, +0x30, 0xE0, 0x03, 0x43, 0x54, 0x04, 0xD1, 0x59, 0x12, 0x6F, 0xA1, 0x30, 0xE0, 0x0B, 0x12, 0xA2, +0xFD, 0x60, 0x2F, 0xE4, 0xFD, 0x7F, 0x02, 0x80, 0x1D, 0xF1, 0xD6, 0x90, 0x9F, 0xA2, 0xE0, 0xB4, +0x02, 0x18, 0xD1, 0xDB, 0x12, 0x82, 0xF0, 0xBF, 0x01, 0x09, 0x90, 0x9F, 0xA9, 0xE0, 0xFF, 0x7D, +0x01, 0x80, 0x03, 0xE4, 0xFD, 0xFF, 0x51, 0xA1, 0x80, 0x08, 0x90, 0x9F, 0xAA, 0xE0, 0x90, 0x9F, +0xA2, 0xF0, 0x90, 0x05, 0x40, 0x74, 0x22, 0xF0, 0x80, 0x27, 0xD1, 0x56, 0x90, 0x9F, 0xA2, 0xE0, +0xB4, 0x02, 0x06, 0x7D, 0x01, 0x7F, 0x04, 0x80, 0x0B, 0x90, 0x9F, 0xA2, 0xE0, 0xB4, 0x08, 0x06, +0x7D, 0x01, 0x7F, 0x0C, 0x51, 0xA1, 0x12, 0xA3, 0x4E, 0x90, 0x9F, 0xA9, 0xF1, 0xEE, 0x12, 0xA8, +0x8C, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0x54, 0x01, 0x90, 0x05, 0x27, 0xE5, 0x54, 0xF0, 0x22, +0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x91, 0xD1, 0x43, 0x54, 0x08, 0x22, 0x90, +0xA0, 0x5F, 0xE0, 0x20, 0xE0, 0x1D, 0x90, 0x9F, 0xA7, 0xE0, 0x64, 0x01, 0x70, 0x15, 0x12, 0x84, +0x33, 0x12, 0x69, 0x3A, 0x60, 0x05, 0x91, 0x8D, 0x02, 0xA8, 0xE1, 0x90, 0x9F, 0xAA, 0xE0, 0x70, +0x02, 0x51, 0x9D, 0x22, 0x90, 0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x7D, 0x78, +0xFF, 0x91, 0xD1, 0x7D, 0x02, 0x7F, 0x03, 0x91, 0xD1, 0x90, 0x06, 0x0A, 0xE0, 0x44, 0x07, 0x12, +0xAC, 0x3E, 0xE4, 0xFF, 0xF1, 0x2F, 0xBF, 0x01, 0x10, 0x12, 0x8C, 0xF1, 0x90, 0x9F, 0xAA, 0xE0, +0x20, 0xE2, 0x09, 0x7D, 0x01, 0x7F, 0x04, 0x41, 0xA1, 0x12, 0xAB, 0xFA, 0x22, 0xFF, 0x13, 0x13, +0x13, 0x54, 0x1F, 0x22, 0xF0, 0x7D, 0x04, 0x7F, 0x01, 0x41, 0x1E, 0x91, 0x93, 0xD1, 0xD5, 0xF1, +0xD6, 0x90, 0x9F, 0xA2, 0x74, 0x04, 0xF0, 0x22, 0x7F, 0x01, 0x51, 0x1E, 0x90, 0x9F, 0xA2, 0x22, +0x7D, 0x2F, 0x12, 0x63, 0x00, 0x7D, 0x08, 0xD1, 0xE8, 0x74, 0x08, 0xF0, 0x22, 0xEF, 0x60, 0x2E, +0xF1, 0x8C, 0x64, 0x01, 0x70, 0x28, 0x90, 0x9F, 0xA4, 0xE0, 0x54, 0xFE, 0xF0, 0x7D, 0x2B, 0x7F, +0x0F, 0x12, 0x49, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x54, 0xBF, 0xF0, 0xF1, 0xE5, 0xBF, 0x01, 0x0E, +0x90, 0x9F, 0xA3, 0xE0, 0x44, 0x40, 0xF0, 0x7D, 0x06, 0xD1, 0xE8, 0x74, 0x06, 0xF0, 0x22, 0x12, +0x86, 0xD3, 0xFE, 0xEF, 0x54, 0x07, 0xFF, 0x12, 0x62, 0x14, 0xE0, 0xFD, 0x7C, 0x00, 0x12, 0x7C, +0xC7, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF, +0x5D, 0x4E, 0x7F, 0x00, 0x60, 0x02, 0x7F, 0x01, 0x22, 0xEF, 0x70, 0x2E, 0x7D, 0x78, 0x7F, 0x02, +0xF1, 0xAB, 0x7D, 0x02, 0x7F, 0x03, 0xF1, 0xAB, 0x7D, 0xC8, 0x7F, 0x02, 0x12, 0x88, 0xAD, 0x12, +0x82, 0xC4, 0xF1, 0x8C, 0x70, 0x05, 0x12, 0xAB, 0x6D, 0x80, 0x06, 0x7D, 0x01, 0x7F, 0x0C, 0x51, +0xA1, 0x90, 0x9F, 0xA3, 0xE0, 0x54, 0xF7, 0x02, 0xAC, 0xAA, 0xC1, 0x94, 0xE4, 0xFF, 0xF1, 0x2F, +0xEF, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x91, 0x93, 0x7D, 0x0C, 0x7F, 0x01, 0x41, +0x1E, 0x7D, 0x02, 0x7F, 0x02, 0xF1, 0xAB, 0x7D, 0x01, 0x7F, 0x02, 0x74, 0x15, 0x12, 0xAD, 0x31, +0xFE, 0xF6, 0x74, 0x30, 0x02, 0x88, 0xB6, 0x12, 0xA8, 0xE1, 0x90, 0x9F, 0xAA, 0xE0, 0x64, 0x0C, +0x60, 0x04, 0x91, 0x8D, 0xF1, 0xE5, 0x22, 0x91, 0x93, 0x90, 0x9F, 0xA1, 0x74, 0x01, 0xF0, 0x22, +0x91, 0x93, 0xF1, 0xD6, 0x80, 0xF3, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, 0x22, 0x12, 0x64, +0xAA, 0x91, 0x93, 0x80, 0xE4, 0x7D, 0x08, 0xE4, 0xFF, 0x02, 0x4C, 0x8B, 0x80, 0xDB, 0xE0, 0xFF, +0x7D, 0x01, 0x41, 0xA1, 0x75, 0xE8, 0x07, 0x75, 0xA8, 0x85, 0x22, 0x7F, 0x81, 0x12, 0x47, 0xAF, +0xEF, 0x54, 0xFE, 0xFD, 0x7F, 0x81, 0x12, 0x46, 0xA0, 0x7F, 0x80, 0x12, 0x47, 0xF7, 0xFD, 0x7F, +0x80, 0x12, 0x46, 0xA0, 0x12, 0xA1, 0xE0, 0x12, 0x3E, 0x11, 0x51, 0x7C, 0x12, 0xA2, 0x21, 0x7F, +0x01, 0x12, 0x43, 0xA5, 0x90, 0xA0, 0xC0, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x43, 0xA5, 0x90, 0xA0, +0xC0, 0xE0, 0x04, 0xF0, 0x12, 0x58, 0x0F, 0x11, 0x93, 0x7F, 0x80, 0x12, 0xAD, 0x39, 0x7F, 0x80, +0x12, 0x46, 0xA0, 0x75, 0x28, 0xFF, 0x12, 0x5F, 0xF4, 0x12, 0x96, 0x89, 0x7B, 0x01, 0x7A, 0xA0, +0x79, 0xF0, 0x51, 0xBC, 0xEF, 0x64, 0x01, 0x70, 0x22, 0x90, 0xA0, 0xF0, 0xE0, 0x54, 0x07, 0xF0, +0xE0, 0xFF, 0x64, 0x07, 0x60, 0x04, 0xEF, 0xB4, 0x04, 0x11, 0x12, 0xA1, 0x91, 0xBF, 0x01, 0x0B, +0x12, 0xAC, 0xA1, 0x44, 0x60, 0xFD, 0x7F, 0x16, 0x12, 0x46, 0xA0, 0x7F, 0x81, 0x12, 0x47, 0xAF, +0xEF, 0x44, 0x04, 0xFD, 0x7F, 0x81, 0x12, 0x46, 0xA0, 0x12, 0xA2, 0x2B, 0x51, 0x9A, 0xE4, 0xFF, +0x02, 0x44, 0x2E, 0x31, 0xD0, 0x12, 0xA0, 0x19, 0x12, 0x55, 0x3E, 0x12, 0xA8, 0x8C, 0x12, 0x59, +0x28, 0x51, 0x76, 0x12, 0xA7, 0x11, 0x7E, 0x00, 0x7F, 0x19, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0xA0, +0x79, 0x91, 0x12, 0x08, 0xAA, 0x12, 0x9E, 0x7A, 0x90, 0xA0, 0x98, 0x12, 0x45, 0x71, 0x90, 0xA0, +0x94, 0x12, 0x08, 0x6D, 0x90, 0x9E, 0x97, 0xE0, 0xFF, 0x64, 0x02, 0x70, 0x22, 0x31, 0xC1, 0x30, +0xE0, 0x02, 0x7E, 0x01, 0x90, 0xA0, 0xA0, 0xEE, 0xF0, 0x31, 0xC1, 0x30, 0xE1, 0x02, 0x7E, 0x01, +0x90, 0xA0, 0xA1, 0xEE, 0xF0, 0x90, 0xFD, 0x80, 0xE0, 0x90, 0x02, 0xFB, 0xF0, 0x80, 0x3A, 0xEF, +0x64, 0x01, 0x70, 0x15, 0x31, 0x5A, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0xA0, 0xA0, 0xEF, 0xF0, +0x31, 0x5A, 0x30, 0xE1, 0x02, 0x7F, 0x01, 0x80, 0x1B, 0x90, 0x9E, 0x97, 0xE0, 0x64, 0x03, 0x70, +0x18, 0x31, 0x53, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0xA0, 0xA0, 0xEF, 0xF0, 0x31, 0x53, 0x30, +0xE1, 0x02, 0x7F, 0x01, 0x90, 0xA0, 0xA1, 0xEF, 0xF0, 0x90, 0xFD, 0x68, 0xE0, 0x44, 0x02, 0xF0, +0x7F, 0x01, 0x51, 0xC3, 0x31, 0x61, 0x12, 0x9B, 0xD6, 0x90, 0xA0, 0x78, 0x74, 0x01, 0xF0, 0x90, +0xA0, 0xAD, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x04, 0x8F, 0xE4, 0xF0, 0x90, 0xA0, 0xBF, 0xE0, 0x54, +0xFE, 0xF0, 0x22, 0x90, 0xFD, 0x78, 0xE0, 0x7F, 0x00, 0x22, 0x90, 0xFD, 0x70, 0xE0, 0x7F, 0x00, +0x22, 0x7E, 0x00, 0x7F, 0x32, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0x5F, 0x12, 0x08, 0xAA, +0x90, 0xA0, 0x60, 0x74, 0x0B, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x90, 0x9E, 0x97, 0xE0, 0xFC, 0x64, +0x02, 0x70, 0x14, 0x31, 0xC1, 0x30, 0xE2, 0x02, 0x7E, 0x01, 0xEE, 0x31, 0xC8, 0xFE, 0x90, 0xA0, +0x62, 0xE0, 0x54, 0xBF, 0x4E, 0xF0, 0x22, 0xEC, 0x64, 0x01, 0x70, 0x09, 0x31, 0x5A, 0x30, 0xE2, +0x02, 0x7F, 0x01, 0x80, 0x0F, 0x90, 0x9E, 0x97, 0xE0, 0x64, 0x03, 0x70, 0x13, 0x31, 0x53, 0x30, +0xE2, 0x02, 0x7F, 0x01, 0xEF, 0x31, 0xC8, 0xFF, 0x90, 0xA0, 0x62, 0xE0, 0x54, 0xBF, 0x4F, 0xF0, +0x22, 0x90, 0xFD, 0x80, 0xE0, 0x7E, 0x00, 0x22, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x54, 0xC0, 0x22, +0xE4, 0xFD, 0xFF, 0x12, 0x86, 0xD3, 0xFE, 0xEF, 0x54, 0x07, 0xFF, 0xED, 0x70, 0x12, 0x51, 0x14, +0xC0, 0x83, 0xC0, 0x82, 0x51, 0x0C, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5E, 0x80, 0x0F, +0x51, 0x14, 0xC0, 0x83, 0xC0, 0x82, 0x51, 0x0C, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4E, 0xD0, +0x82, 0xD0, 0x83, 0xF0, 0x51, 0x1F, 0x90, 0x9F, 0x9C, 0xEF, 0xF0, 0x22, 0xE0, 0xFE, 0x74, 0x01, +0xA8, 0x07, 0x08, 0x22, 0x74, 0x8C, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x9F, 0xF5, 0x83, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7D, 0x10, 0xED, 0x14, 0xF9, 0x24, 0x8C, 0x51, 0x17, 0xE0, +0x60, 0x3B, 0x7C, 0x08, 0xEC, 0x14, 0x90, 0xA2, 0x34, 0xF0, 0x74, 0x8C, 0x29, 0x51, 0x17, 0xE0, +0xFB, 0x7A, 0x00, 0x90, 0xA2, 0x34, 0x12, 0x7C, 0xC5, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5A, 0xFE, 0xEF, 0x5B, 0x4E, 0x60, 0x0F, 0xE9, 0x75, 0xF0, 0x08, +0xA4, 0xFF, 0x90, 0xA2, 0x34, 0xE0, 0x2F, 0x04, 0xFF, 0x80, 0x06, 0xDC, 0xC7, 0xDD, 0xB9, 0x7F, +0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0xAB, 0xE3, 0x02, 0x08, 0xAA, 0x90, 0x01, 0x01, 0xE0, +0x44, 0x04, 0xF0, 0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x12, 0x96, 0xF8, 0x90, 0x01, 0x99, 0xE0, +0x44, 0xC0, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x80, 0xF0, 0x22, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0xF1, +0x51, 0xBC, 0xBF, 0x01, 0x16, 0x90, 0xA0, 0xF1, 0xE0, 0x54, 0x30, 0xFF, 0xBF, 0x20, 0x07, 0x90, +0xA0, 0xEE, 0x74, 0x01, 0xF0, 0x22, 0xE4, 0x90, 0xA0, 0xEE, 0xF0, 0x22, 0x7F, 0xFB, 0x7E, 0x01, +0x02, 0x34, 0xC1, 0x90, 0xA0, 0x84, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, +0x07, 0x78, 0x74, 0x09, 0xF0, 0x22, 0x90, 0xA0, 0xBF, 0xE0, 0x30, 0xE0, 0x1D, 0xEF, 0x24, 0xFD, +0x60, 0x0E, 0x24, 0xFA, 0x60, 0x0E, 0x24, 0xFC, 0x60, 0x0E, 0x24, 0x0C, 0x7F, 0x02, 0x80, 0x0A, +0x7F, 0x03, 0x80, 0x06, 0x7F, 0x0B, 0x80, 0x02, 0x7F, 0x0E, 0x90, 0x07, 0x78, 0xEF, 0xF0, 0x22, +0x7F, 0xFF, 0x12, 0x49, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x4C, 0x22, 0x91, +0xA3, 0x91, 0x8D, 0x91, 0x8D, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x12, 0x46, 0xA0, 0x90, 0x01, 0x00, +0x74, 0x3F, 0xF0, 0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x20, 0x12, 0x9D, +0x47, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x04, 0x7F, 0x01, 0x51, 0xC3, 0x12, 0x9D, 0x3F, 0x30, 0xE0, +0x31, 0x90, 0xA0, 0xA0, 0xE0, 0x60, 0x08, 0x90, 0xA2, 0x2A, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, +0x90, 0xA2, 0x2A, 0xF0, 0xEF, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA2, 0x2B, +0xF0, 0x80, 0x06, 0x90, 0xA2, 0x2B, 0x74, 0x02, 0xF0, 0x90, 0xA2, 0x2A, 0x71, 0x7F, 0x7F, 0x01, +0x51, 0xC3, 0x90, 0xA0, 0x4F, 0xE0, 0x60, 0x02, 0xE4, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, +0xFF, 0xA3, 0xE0, 0xFD, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x26, 0x8D, 0x27, 0x90, +0xA0, 0x62, 0x12, 0x4F, 0xD3, 0x30, 0xE0, 0x02, 0x81, 0x74, 0x90, 0xA0, 0xA1, 0xE0, 0x70, 0x57, +0xE5, 0x26, 0x64, 0x02, 0x60, 0x23, 0xE5, 0x27, 0x70, 0x1F, 0x91, 0x79, 0xE5, 0x26, 0x90, 0xA1, +0xC5, 0xB4, 0x01, 0x05, 0x12, 0x45, 0x71, 0x80, 0x08, 0x12, 0xAD, 0x29, 0xEE, 0x44, 0x02, 0xFE, +0xEC, 0x91, 0x87, 0x12, 0x47, 0xCB, 0x12, 0x47, 0xD6, 0xE5, 0x27, 0x64, 0x02, 0x70, 0x02, 0x81, +0x74, 0xE5, 0x27, 0x70, 0x02, 0x81, 0x74, 0x91, 0x79, 0x90, 0xA0, 0xA0, 0xE0, 0x90, 0xA1, 0xC5, +0x60, 0x05, 0x12, 0xAD, 0x29, 0x80, 0x07, 0x12, 0x45, 0x71, 0xEE, 0x44, 0x02, 0xFE, 0x91, 0x86, +0x12, 0x47, 0xCB, 0x7F, 0x48, 0x80, 0x78, 0xE5, 0x26, 0x64, 0x02, 0x60, 0x23, 0x12, 0xAB, 0x8D, +0x91, 0x86, 0xE5, 0x26, 0x90, 0xA1, 0xC5, 0xB4, 0x01, 0x08, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x01, +0x80, 0x06, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x02, 0xFF, 0x91, 0x86, 0x12, 0x47, 0xCB, 0xF1, 0xD1, +0xE5, 0x27, 0x64, 0x02, 0x60, 0x4E, 0x12, 0x97, 0x6E, 0xE4, 0xFF, 0x91, 0x86, 0xE5, 0x27, 0x70, +0x0A, 0x12, 0xAD, 0x21, 0x44, 0x77, 0xFF, 0x91, 0x86, 0x80, 0x2F, 0x12, 0xAD, 0x21, 0x44, 0x66, +0xFF, 0x91, 0x86, 0x12, 0xAB, 0x8D, 0xF1, 0xD8, 0x90, 0xA0, 0xA0, 0xE0, 0x90, 0xA1, 0xC9, 0x60, +0x08, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x02, 0x80, 0x06, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x01, 0xFF, +0xF1, 0xD8, 0x90, 0xA1, 0xC9, 0x12, 0x47, 0xCE, 0xF1, 0xD1, 0x12, 0x47, 0xCB, 0x7F, 0x30, 0x7E, +0x09, 0x12, 0x38, 0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x37, 0x4E, +0xE4, 0xFF, 0xEE, 0x54, 0xF0, 0xFE, 0xEC, 0x90, 0xA1, 0xC5, 0x02, 0x08, 0x6D, 0x54, 0xFE, 0xFD, +0x7F, 0x02, 0x12, 0x46, 0xA0, 0x7F, 0x02, 0x12, 0x47, 0xAF, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x02, +0x12, 0x46, 0xA0, 0x7F, 0x02, 0x12, 0x47, 0xAF, 0xEF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, +0xB7, 0x74, 0x09, 0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, 0x12, 0x9D, 0x47, 0x13, 0x54, 0x1F, 0x30, +0xE0, 0x04, 0x7F, 0x03, 0x51, 0xC3, 0x90, 0xA0, 0x7A, 0xE0, 0x20, 0xE0, 0x31, 0x12, 0x9D, 0x3F, +0x30, 0xE0, 0x2B, 0x90, 0xA0, 0xA0, 0xE0, 0x60, 0x07, 0xE4, 0x90, 0xA2, 0x28, 0xF0, 0x80, 0x06, +0x90, 0xA2, 0x28, 0x74, 0x01, 0xF0, 0xEF, 0xC4, 0x13, 0x54, 0x07, 0x90, 0xA2, 0x29, 0x30, 0xE0, +0x05, 0x74, 0x01, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0x90, 0xA2, 0x28, 0x71, 0x7F, 0x91, 0xA3, +0x44, 0x01, 0xFD, 0x7F, 0x02, 0x12, 0x46, 0xA0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xF0, 0xEF, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0xE4, 0xFF, 0x12, +0x8A, 0x84, 0x90, 0xA0, 0x63, 0x12, 0x8D, 0x05, 0x30, 0xE0, 0x02, 0x91, 0xAA, 0x90, 0xA0, 0x63, +0xE0, 0x30, 0xE0, 0x04, 0x7F, 0x01, 0x80, 0x37, 0x90, 0xA0, 0x5F, 0x12, 0x4F, 0xD3, 0x30, 0xE0, +0x04, 0x7F, 0x0D, 0x80, 0x2A, 0x90, 0xA0, 0x62, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x10, +0xEF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x04, 0x7F, 0x09, 0x80, 0x13, 0x7F, 0x03, 0x80, 0x0F, +0x90, 0xA0, 0x62, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x04, 0x7F, 0x03, 0x80, 0x02, 0x7F, 0x09, 0x51, +0xC3, 0x90, 0xA1, 0xF0, 0xE0, 0x64, 0x03, 0x70, 0x6B, 0x12, 0x4F, 0xD0, 0x30, 0xE0, 0x60, 0x90, +0xA0, 0x69, 0xE0, 0xFF, 0x90, 0xA0, 0x74, 0xE0, 0xFE, 0xD3, 0x9F, 0x40, 0x37, 0xEE, 0x75, 0xF0, +0x03, 0xA4, 0xFF, 0x90, 0xA0, 0x6B, 0xE0, 0xFE, 0xC3, 0xEF, 0x9E, 0xFF, 0x24, 0x03, 0xFD, 0xE4, +0x33, 0xFC, 0x90, 0xA0, 0x61, 0xE0, 0xFE, 0xD3, 0x9D, 0xEC, 0x12, 0xAB, 0xF3, 0x40, 0x08, 0xEE, +0x9F, 0x90, 0xA1, 0xF3, 0xF0, 0x80, 0x06, 0x90, 0xA1, 0xF3, 0x74, 0x03, 0xF0, 0x90, 0xA1, 0xF3, +0xF1, 0x98, 0x80, 0x14, 0x90, 0xA0, 0x6C, 0xE0, 0xFF, 0xD1, 0xEC, 0x90, 0xA0, 0x67, 0x74, 0x04, +0xF0, 0xE4, 0x90, 0xA0, 0x72, 0x12, 0x8E, 0xBF, 0xE4, 0x90, 0xA0, 0x74, 0xF0, 0x80, 0x05, 0x90, +0xA0, 0x61, 0xF1, 0x98, 0x90, 0xA0, 0x5F, 0x12, 0x56, 0xE4, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA1, +0xF2, 0xF0, 0x80, 0x06, 0x90, 0xA1, 0xF2, 0x74, 0x01, 0xF0, 0x12, 0x9B, 0xCD, 0x20, 0xE0, 0x13, +0x90, 0xA0, 0xA0, 0xE0, 0x60, 0x07, 0xE4, 0x90, 0xA1, 0xF1, 0xF0, 0x80, 0x06, 0x90, 0xA1, 0xF1, +0x74, 0x01, 0xF0, 0x90, 0xA1, 0xF1, 0x71, 0x7F, 0x90, 0xA0, 0x71, 0x74, 0x01, 0xF0, 0x12, 0x9B, +0xC4, 0x30, 0xE0, 0x0D, 0x90, 0xA1, 0xF0, 0xE0, 0x70, 0x3B, 0xFD, 0xFF, 0x12, 0x49, 0x22, 0x80, +0x34, 0x12, 0x9B, 0xB3, 0x30, 0xE0, 0x1A, 0x90, 0xA0, 0x65, 0xE0, 0x44, 0x20, 0xF0, 0x90, 0xA0, +0x51, 0xE0, 0x60, 0x04, 0x7D, 0x01, 0x80, 0x18, 0x12, 0x5C, 0x93, 0x7D, 0x01, 0x7F, 0x0C, 0x80, +0x11, 0x90, 0xA1, 0xF0, 0xE0, 0xB4, 0x03, 0x0D, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x07, 0xE4, 0xFD, +0x7F, 0x04, 0x12, 0x5A, 0xA1, 0x90, 0xA0, 0x51, 0xE0, 0x60, 0x18, 0x90, 0xA1, 0xF0, 0xE0, 0x70, +0x04, 0x7D, 0x04, 0x80, 0x0A, 0x90, 0xA1, 0xF0, 0xE0, 0x64, 0x03, 0x70, 0x31, 0x7D, 0x0B, 0x7F, +0x6F, 0x80, 0x28, 0x90, 0xA1, 0xF0, 0xE0, 0x70, 0x04, 0xFD, 0xFF, 0x80, 0x1E, 0x90, 0xA1, 0xF0, +0xE0, 0xB4, 0x03, 0x1A, 0x90, 0xA0, 0x5F, 0x12, 0x8F, 0xB4, 0x20, 0xE0, 0x0B, 0xEF, 0x13, 0x13, +0x54, 0x3F, 0x30, 0xE0, 0x03, 0x12, 0x6F, 0xDF, 0xE4, 0xFD, 0xFF, 0x12, 0x49, 0x22, 0x90, 0xA0, +0x62, 0x12, 0x56, 0xE4, 0x30, 0xE0, 0x05, 0x7F, 0x01, 0x12, 0x97, 0xC6, 0x90, 0xA0, 0x63, 0xE0, +0xC3, 0x13, 0x30, 0xE0, 0x0E, 0x90, 0x06, 0xCD, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x06, 0xCF, 0xE0, +0x44, 0x10, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xC3, 0x9F, 0xFF, 0xE4, 0x90, 0xA1, 0xD9, +0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x6C, 0x7E, 0x01, 0x02, 0x48, 0x34, 0xAD, 0x07, +0xED, 0x70, 0x19, 0xF1, 0x87, 0x70, 0x02, 0x80, 0x17, 0xBC, 0x01, 0x02, 0x80, 0x19, 0xF1, 0x87, +0xBC, 0x02, 0x02, 0x80, 0x1B, 0xEC, 0x64, 0x03, 0x70, 0x21, 0x80, 0x1B, 0xF1, 0x8F, 0x70, 0x04, +0x7F, 0x01, 0x80, 0x15, 0xBC, 0x01, 0x04, 0x7F, 0x03, 0x80, 0x0E, 0xF1, 0x8F, 0xBC, 0x02, 0x04, +0x7F, 0x09, 0x80, 0x05, 0xBC, 0x03, 0x04, 0x7F, 0x0D, 0x51, 0xC3, 0x90, 0xA0, 0xAD, 0xE0, 0xC4, +0x13, 0x54, 0x07, 0x30, 0xE0, 0x39, 0xED, 0x70, 0x1B, 0xA3, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, +0xE0, 0x07, 0xE4, 0x90, 0xA1, 0x2B, 0xF0, 0x80, 0x02, 0xF1, 0x80, 0x90, 0xA1, 0x2B, 0xE0, 0xFD, +0xE4, 0xFF, 0x80, 0x19, 0x90, 0xA0, 0xAE, 0x12, 0x4F, 0xD3, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA1, +0x2B, 0xF0, 0x80, 0x02, 0xF1, 0x80, 0x90, 0xA1, 0x2B, 0xE0, 0xFD, 0x7F, 0x01, 0x71, 0x84, 0x22, +0x90, 0xA1, 0x2B, 0x74, 0x01, 0xF0, 0x22, 0x90, 0xA0, 0xAE, 0xE0, 0x54, 0x03, 0xFC, 0x22, 0x90, +0xA0, 0xAE, 0xE0, 0xC4, 0x54, 0x03, 0xFC, 0x22, 0xE0, 0xFF, 0xD1, 0xEC, 0x90, 0xA0, 0x72, 0xE0, +0x04, 0xF0, 0x22, 0x7D, 0x12, 0x7F, 0xFF, 0x12, 0x49, 0x22, 0x7F, 0x01, 0x51, 0xC3, 0x12, 0x97, +0x7D, 0x61, 0x84, 0x90, 0xA0, 0x7A, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xE1, 0xF0, 0x90, 0xA0, 0x7F, +0xE0, 0xFF, 0x51, 0xC3, 0x90, 0xA0, 0x80, 0x71, 0x7F, 0x91, 0xAA, 0xE4, 0xFD, 0xFF, 0x02, 0x49, +0x22, 0x7F, 0x2C, 0x7E, 0x09, 0x02, 0x38, 0x45, 0xEC, 0x90, 0xA1, 0xC9, 0x02, 0x08, 0x6D, 0x7D, +0x20, 0x71, 0x00, 0x90, 0x9F, 0xA1, 0x74, 0x02, 0xF0, 0x22, 0x71, 0x05, 0x80, 0xF5, 0xE4, 0x90, +0xA0, 0xF3, 0xF0, 0x90, 0xA0, 0xF3, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0xEE, 0x90, 0x01, 0xC4, 0xF0, +0x74, 0x67, 0xA3, 0xF0, 0x12, 0x3E, 0x44, 0xBF, 0x01, 0x03, 0x12, 0x31, 0xFC, 0xC2, 0xAF, 0x90, +0x9F, 0xA7, 0xE0, 0x60, 0x0E, 0x90, 0x9F, 0xAA, 0xE0, 0xFF, 0x90, 0x9F, 0xA9, 0xE0, 0x6F, 0x60, +0x02, 0x11, 0x44, 0xC2, 0xAF, 0x12, 0xA1, 0xED, 0xBF, 0x01, 0x03, 0x12, 0x95, 0x3F, 0xD2, 0xAF, +0xD2, 0xAF, 0x90, 0xA0, 0xEE, 0xE0, 0xB4, 0x01, 0x03, 0x12, 0xA8, 0x12, 0x12, 0x4F, 0xFE, 0x12, +0x42, 0xDD, 0x80, 0xAF, 0x90, 0x9F, 0x9E, 0xE0, 0x90, 0x9F, 0xA9, 0x30, 0xE0, 0x05, 0xE0, 0xFF, +0x02, 0xA8, 0xC3, 0x02, 0x5F, 0xEE, 0xE4, 0xFF, 0x12, 0x5F, 0x2F, 0xBF, 0x01, 0x0E, 0x90, 0x9F, +0xA7, 0xE0, 0x60, 0x08, 0x11, 0x6D, 0x54, 0x07, 0x70, 0x02, 0x11, 0x44, 0x22, 0x90, 0x9F, 0xAB, +0xE0, 0x54, 0xFE, 0xF0, 0x22, 0xE4, 0xF5, 0x63, 0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x63, 0x54, 0xC0, +0x70, 0x07, 0x11, 0x6D, 0x54, 0xFD, 0xF0, 0x80, 0xBB, 0xE5, 0x63, 0x30, 0xE6, 0x17, 0x90, 0x9F, +0xA7, 0xE0, 0x64, 0x01, 0x70, 0x11, 0x31, 0x33, 0x64, 0x02, 0x60, 0x04, 0xF1, 0xDF, 0x80, 0x07, +0x12, 0x5F, 0xB7, 0x80, 0x02, 0x11, 0x6D, 0xE5, 0x63, 0x90, 0x9F, 0xAB, 0x30, 0xE7, 0x0D, 0xF1, +0xBA, 0x12, 0x48, 0x2C, 0x90, 0x9F, 0xA3, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, +0x22, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0xA1, 0x1D, 0xF0, 0xE0, 0xFD, 0x54, 0xC0, 0x70, 0x04, 0x11, +0x6D, 0x80, 0x5C, 0xED, 0x30, 0xE6, 0x3E, 0x90, 0x9F, 0xA7, 0xE0, 0x64, 0x02, 0x70, 0x27, 0x90, +0x9F, 0xA3, 0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0, 0x09, 0x90, 0x9F, 0xAB, 0xE0, 0x44, 0x01, 0xF0, +0x80, 0x1A, 0x31, 0x3A, 0x64, 0x01, 0x70, 0x1F, 0x90, 0x9F, 0xAB, 0xE0, 0x44, 0x04, 0xF0, 0x7F, +0x01, 0x12, 0x4D, 0xD5, 0x80, 0x11, 0x31, 0x33, 0x64, 0x02, 0x60, 0x04, 0xF1, 0xDF, 0x80, 0x07, +0x12, 0x5F, 0xB7, 0x80, 0x02, 0x11, 0x6D, 0x90, 0xA1, 0x1D, 0xE0, 0x90, 0x9F, 0xAB, 0x30, 0xE7, +0x0D, 0xF1, 0xBA, 0x12, 0x48, 0x2C, 0x90, 0x9F, 0xA3, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54, +0xFD, 0xF0, 0x22, 0x90, 0x9F, 0xAB, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x9F, 0xA5, 0xE0, 0x54, 0x0F, +0x22, 0xF1, 0x66, 0x12, 0x06, 0x89, 0xFF, 0x54, 0x7F, 0x90, 0x9F, 0xA7, 0xF0, 0xEF, 0x12, 0x56, +0xE5, 0xA3, 0x51, 0x86, 0xFF, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFE, 0x90, 0x9F, 0xA5, 0xE0, 0x54, +0xF0, 0x4E, 0xF0, 0x12, 0x57, 0x09, 0x54, 0x01, 0x25, 0xE0, 0xFE, 0x90, 0x9F, 0xA3, 0xE0, 0x54, +0xFD, 0x4E, 0xF0, 0xEF, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x31, 0x3A, 0x12, 0x56, 0xDC, 0x90, +0x9F, 0xA6, 0xF0, 0x51, 0x80, 0x30, 0xE0, 0x52, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0xC3, 0x94, 0x04, +0x90, 0x9F, 0xBA, 0x50, 0x04, 0xEF, 0xF0, 0x80, 0x2A, 0x74, 0x03, 0xF0, 0x51, 0x73, 0xE9, 0x24, +0x06, 0xF9, 0xE4, 0x3A, 0xFA, 0x12, 0x06, 0x89, 0xFF, 0x74, 0x03, 0x24, 0xFD, 0xFE, 0xEF, 0xC4, +0x54, 0x0F, 0xFD, 0xEF, 0x54, 0x0F, 0xFF, 0xED, 0x2E, 0x54, 0x0F, 0xFE, 0xC4, 0x54, 0xF0, 0x4F, +0x12, 0x06, 0xCF, 0x51, 0x73, 0x51, 0x80, 0xC4, 0x54, 0x0F, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x9F, +0xAF, 0x50, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x02, 0xEF, 0xF0, 0x51, 0x73, 0xB1, 0x28, 0xFD, 0x7F, +0x02, 0x12, 0x5A, 0x1E, 0x51, 0x73, 0x51, 0x7A, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0xA0, 0x50, 0xF1, +0x44, 0xFF, 0x51, 0x79, 0xB1, 0x2E, 0xFF, 0x90, 0xA0, 0x50, 0xF1, 0x7C, 0x4E, 0xFF, 0x51, 0x79, +0xF1, 0x8D, 0x90, 0xA0, 0x50, 0x12, 0x9F, 0x77, 0x4E, 0xFF, 0x51, 0x79, 0xF1, 0x3D, 0x4E, 0x90, +0xA0, 0x50, 0xF0, 0xF1, 0xA4, 0x20, 0xE0, 0x29, 0xEF, 0xC3, 0x13, 0x20, 0xE0, 0x0B, 0x75, 0x52, +0x01, 0x90, 0xA0, 0xA0, 0xE0, 0x60, 0x0B, 0x80, 0x0E, 0xE4, 0xF5, 0x52, 0x90, 0xA0, 0xA0, 0xE0, +0x60, 0x05, 0xE4, 0xF5, 0x51, 0x80, 0x03, 0x75, 0x51, 0x01, 0xAD, 0x52, 0xAF, 0x51, 0x12, 0x63, +0x84, 0x51, 0x73, 0x90, 0xA1, 0x04, 0x12, 0x45, 0xBE, 0x12, 0xA9, 0x27, 0x90, 0x9F, 0xA7, 0xE0, +0xFF, 0x12, 0x5F, 0x59, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x12, 0x90, 0xA1, 0x04, 0x12, 0x45, 0xB5, +0x51, 0x87, 0x54, 0x0F, 0xFF, 0x12, 0x56, 0xDE, 0xFD, 0x12, 0xA9, 0x4C, 0x22, 0x90, 0xA1, 0x01, +0x12, 0x45, 0xBE, 0x90, 0xA1, 0x01, 0x02, 0x45, 0xB5, 0xF0, 0x90, 0x00, 0x05, 0x02, 0x06, 0xA2, +0x90, 0x00, 0x06, 0x02, 0x06, 0xA2, 0xF0, 0x90, 0x00, 0x01, 0x02, 0x06, 0xA2, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0x66, 0x12, 0x8F, 0xC9, 0x90, 0xA0, 0x5F, 0xF1, 0x44, 0xFF, 0xF0, +0x12, 0x06, 0x89, 0xB1, 0x2E, 0xFF, 0x90, 0xA0, 0x5F, 0xF1, 0xAC, 0xF1, 0x97, 0x90, 0xA0, 0x5F, +0xF1, 0x3B, 0xF1, 0xB4, 0xF1, 0x74, 0x90, 0xA0, 0x5F, 0xF0, 0x12, 0x57, 0x09, 0xFF, 0x54, 0x01, +0xFE, 0x90, 0xA0, 0x62, 0xF1, 0x44, 0xFF, 0xF0, 0x12, 0x57, 0x09, 0xB1, 0x2E, 0xFF, 0x90, 0xA0, +0x62, 0xF0, 0xEE, 0x54, 0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x12, 0x57, 0x09, 0xF1, +0x97, 0x90, 0xA0, 0x62, 0xF1, 0x3B, 0x4E, 0xFF, 0xF0, 0x12, 0x57, 0x09, 0xF1, 0x74, 0x90, 0xA0, +0x62, 0xB1, 0x27, 0xFF, 0x54, 0x20, 0xFE, 0x90, 0xA0, 0x63, 0xE0, 0x54, 0xDF, 0x4E, 0xFE, 0xF0, +0xEF, 0x54, 0x40, 0xFF, 0xEE, 0x54, 0xBF, 0x4F, 0xB1, 0x26, 0xFE, 0x54, 0x80, 0xFD, 0xEF, 0x54, +0x7F, 0x4D, 0xFF, 0x90, 0xA0, 0x63, 0xF0, 0xEE, 0x54, 0x01, 0xFE, 0xEF, 0x54, 0xFE, 0x4E, 0xB1, +0x26, 0xB1, 0x2E, 0xFF, 0x90, 0xA0, 0x63, 0xF0, 0xEE, 0x54, 0x02, 0xFE, 0xEF, 0x54, 0xFD, 0x4E, +0xB1, 0x26, 0xF1, 0x8D, 0x90, 0xA0, 0x63, 0xF1, 0x7C, 0x4E, 0xF0, 0x12, 0x8D, 0x05, 0x20, 0xE0, +0x06, 0x12, 0x64, 0xAA, 0x12, 0x5C, 0x93, 0x51, 0x73, 0x12, 0x06, 0x89, 0x20, 0xE0, 0x02, 0x81, +0x93, 0x90, 0x05, 0x54, 0xE0, 0x90, 0xA0, 0x70, 0xF0, 0xE0, 0xC3, 0x13, 0x90, 0xA0, 0x6F, 0x12, +0x85, 0xA7, 0x30, 0xE0, 0x0E, 0x51, 0x87, 0x90, 0xA0, 0x60, 0x12, 0x56, 0xDD, 0x90, 0xA0, 0x61, +0xF0, 0x80, 0x41, 0x51, 0x87, 0xFF, 0xC3, 0x94, 0x2A, 0x50, 0x12, 0xEF, 0xC3, 0x94, 0x03, 0x90, +0xA0, 0x60, 0x50, 0x05, 0x74, 0x03, 0xF0, 0x80, 0x0A, 0xEF, 0xF0, 0x80, 0x06, 0x90, 0xA0, 0x60, +0x74, 0x2A, 0xF0, 0x12, 0x56, 0xDE, 0xFF, 0xC3, 0x94, 0x2A, 0x50, 0x12, 0xEF, 0xC3, 0x94, 0x03, +0x90, 0xA0, 0x61, 0x50, 0x05, 0x74, 0x03, 0xF0, 0x80, 0x0A, 0xEF, 0xF0, 0x80, 0x06, 0x90, 0xA0, +0x61, 0x74, 0x2A, 0xF0, 0x12, 0x4F, 0xD0, 0x30, 0xE0, 0x3D, 0x90, 0xA0, 0x60, 0xE0, 0x75, 0xF0, +0x03, 0x84, 0x90, 0xA0, 0x68, 0xF0, 0xE0, 0xC3, 0x13, 0xA3, 0xF0, 0x90, 0xA0, 0x61, 0xE0, 0x75, +0xF0, 0x03, 0x84, 0x90, 0xA0, 0x6A, 0xF0, 0x90, 0xA0, 0x60, 0xE0, 0xC3, 0x13, 0x90, 0xA0, 0x6B, +0xF0, 0x90, 0xA0, 0x61, 0xE0, 0xC3, 0x13, 0x90, 0xA0, 0x6C, 0xF0, 0x90, 0x01, 0x3E, 0x74, 0x08, +0xF0, 0xFD, 0x7F, 0x02, 0x12, 0x88, 0xD0, 0xE4, 0x90, 0xA0, 0x9E, 0xF0, 0x12, 0x57, 0x03, 0xC4, +0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x39, 0x90, 0xA0, 0x5F, 0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0, +0x07, 0xEF, 0x12, 0x56, 0xE5, 0x30, 0xE0, 0x28, 0x12, 0x06, 0x89, 0x13, 0x13, 0x13, 0x54, 0x1F, +0x30, 0xE0, 0x08, 0x90, 0xA0, 0xA0, 0xE0, 0x60, 0x08, 0x80, 0x0B, 0x90, 0xA0, 0xA0, 0xE0, 0x60, +0x05, 0x75, 0x51, 0x01, 0x80, 0x03, 0xE4, 0xF5, 0x51, 0x7D, 0x02, 0xAF, 0x51, 0x12, 0x63, 0x84, +0x12, 0x9B, 0xB3, 0x30, 0xE0, 0x12, 0x12, 0x9B, 0xBB, 0x30, 0xE0, 0x07, 0x7D, 0x04, 0x7F, 0x02, +0x12, 0x5A, 0x1E, 0xF1, 0x6C, 0x74, 0x11, 0xF0, 0x90, 0x05, 0x58, 0x74, 0x02, 0xF0, 0x90, 0xA0, +0x67, 0xE0, 0xFF, 0xB4, 0x01, 0x08, 0x90, 0xA0, 0x72, 0x74, 0x01, 0xF0, 0x80, 0x1E, 0xEF, 0xB4, +0x04, 0x08, 0x90, 0xA0, 0x72, 0x74, 0x04, 0xF0, 0x80, 0x12, 0xEF, 0xB4, 0x06, 0x08, 0x90, 0xA0, +0x72, 0x74, 0x02, 0xF0, 0x80, 0x06, 0xEF, 0xB4, 0x07, 0x02, 0xF1, 0xD1, 0xE4, 0x90, 0xA0, 0x67, +0xF0, 0x80, 0x56, 0x12, 0x57, 0x03, 0xF1, 0xA5, 0x30, 0xE0, 0x05, 0x75, 0x52, 0x02, 0x80, 0x11, +0x12, 0x06, 0x89, 0x12, 0x5E, 0xCD, 0x30, 0xE0, 0x05, 0x75, 0x52, 0x01, 0x80, 0x03, 0xE4, 0xF5, +0x52, 0x12, 0x9B, 0xD6, 0x90, 0xA0, 0xBF, 0xE0, 0x30, 0xE0, 0x04, 0x7D, 0xAC, 0x80, 0x02, 0x7D, +0x2C, 0x7F, 0x40, 0x12, 0x46, 0xA0, 0x12, 0x57, 0x03, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, +0x04, 0x7F, 0x03, 0x80, 0x02, 0x7F, 0x01, 0x12, 0x62, 0xC3, 0xAD, 0x52, 0x7F, 0x02, 0x12, 0x63, +0x84, 0x12, 0x5C, 0x93, 0xF1, 0x6C, 0x74, 0x43, 0xF0, 0x12, 0xAC, 0xCE, 0x90, 0xA0, 0x71, 0xF0, +0x90, 0xA0, 0x62, 0x12, 0x56, 0xE4, 0x30, 0xE0, 0x09, 0x90, 0xA0, 0x91, 0xE0, 0x44, 0x02, 0xF0, +0x80, 0x0C, 0x7F, 0x01, 0x12, 0x97, 0xC6, 0x90, 0xA0, 0x91, 0xE0, 0x54, 0xFD, 0xF0, 0x7F, 0x03, +0x12, 0x8A, 0x84, 0x90, 0xA0, 0x5F, 0xE0, 0x20, 0xE0, 0x07, 0x90, 0xA0, 0x63, 0xE0, 0x54, 0xBF, +0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xFF, 0xF0, 0x90, 0x00, 0x04, 0x02, 0x06, 0xA2, 0xFE, 0x54, +0x04, 0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0x22, 0x90, 0x02, 0x09, 0x12, 0x9C, 0xAD, 0x90, 0x9E, 0x98, +0x51, 0x86, 0x25, 0x51, 0x90, 0x9E, 0x99, 0x12, 0x56, 0xDD, 0x25, 0x51, 0x90, 0x9E, 0x9A, 0xF0, +0x12, 0x57, 0x09, 0x25, 0x51, 0x90, 0x9E, 0x9B, 0xB1, 0x27, 0x25, 0x51, 0x90, 0x9E, 0x9C, 0x51, +0x79, 0x25, 0x51, 0x90, 0x9E, 0x9D, 0xF0, 0x51, 0x80, 0x25, 0x51, 0x90, 0x9E, 0x9E, 0xF0, 0x22, +0x12, 0x06, 0x89, 0xF5, 0x51, 0x51, 0x87, 0xF5, 0x54, 0x12, 0x56, 0xDE, 0xF5, 0x55, 0x12, 0x57, +0x09, 0xF5, 0x56, 0xB1, 0x28, 0xF5, 0x57, 0x51, 0x7A, 0xF5, 0x58, 0x51, 0x80, 0xF5, 0x59, 0xE5, +0x51, 0x12, 0x45, 0xC7, 0x6D, 0xAD, 0x00, 0x6D, 0xB5, 0x01, 0x6D, 0xBD, 0x02, 0x6D, 0xC5, 0x03, +0x6D, 0xCD, 0x04, 0x6D, 0xD5, 0x05, 0x6D, 0xDD, 0x06, 0x00, 0x00, 0x6D, 0xF0, 0x75, 0x52, 0x02, +0x75, 0x53, 0x29, 0x80, 0x41, 0x75, 0x52, 0x06, 0x75, 0x53, 0x2A, 0x80, 0x39, 0x75, 0x52, 0x01, +0x75, 0x53, 0x31, 0x80, 0x31, 0x75, 0x52, 0x01, 0x75, 0x53, 0x32, 0x80, 0x29, 0x75, 0x52, 0x06, +0x75, 0x53, 0x33, 0x80, 0x21, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x54, 0xC1, 0x6D, 0x90, 0xA0, 0xA2, +0x12, 0xAD, 0x09, 0xA3, 0xE5, 0x56, 0xF0, 0xA3, 0xE5, 0x57, 0xF0, 0xA3, 0xE5, 0x58, 0xF0, 0x22, +0x75, 0x52, 0x01, 0x75, 0x53, 0xFF, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x54, 0xAD, 0x52, 0xAF, 0x53, +0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xE1, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, +0x12, 0x45, 0xBE, 0x12, 0xAB, 0x37, 0x70, 0x22, 0x90, 0xFD, 0x58, 0xE0, 0x20, 0xE0, 0x13, 0x90, +0xA1, 0xE1, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0x12, 0x45, 0xB5, 0x12, 0x9D, 0x9A, 0x7F, 0x01, +0x80, 0x0E, 0x7F, 0x01, 0xF1, 0x53, 0x7F, 0x02, 0x80, 0x06, 0x7F, 0x02, 0xF1, 0x53, 0x7F, 0x03, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x51, 0x6D, 0x12, 0x06, 0x89, 0x90, 0xA0, 0xAA, 0x51, 0x86, 0x90, +0xA0, 0xAB, 0x12, 0x56, 0xDD, 0x90, 0xA0, 0xAC, 0xF0, 0x90, 0xA0, 0x87, 0xE0, 0x44, 0x01, 0xF0, +0x51, 0x73, 0xF1, 0x85, 0xB4, 0x02, 0x05, 0x7F, 0x40, 0x12, 0x98, 0x0D, 0x22, 0x90, 0xA1, 0x01, +0x74, 0x0A, 0xF0, 0x90, 0xA1, 0x0F, 0x74, 0x06, 0xF0, 0x12, 0x06, 0x89, 0x90, 0xA1, 0x03, 0x51, +0x86, 0x90, 0xA1, 0x04, 0x12, 0x56, 0xDD, 0x90, 0xA1, 0x05, 0xF0, 0x12, 0x57, 0x09, 0x90, 0xA1, +0x06, 0xB1, 0x27, 0x90, 0xA1, 0x07, 0x51, 0x79, 0x90, 0xA1, 0x08, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, +0x79, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x9F, 0x87, 0xE0, 0xFF, 0x70, 0x06, +0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x9F, 0x88, 0xE0, 0xB5, 0x07, 0x04, +0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02, 0xF0, +0x80, 0x29, 0xC0, 0x01, 0x90, 0x9F, 0x88, 0xE0, 0x12, 0xA1, 0x59, 0xA8, 0x01, 0xFC, 0x7D, 0x01, +0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x06, 0x63, 0x90, 0x9F, 0x88, 0xF1, 0xD8, 0xB4, 0x0A, +0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x9F, 0x88, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x51, 0x6D, 0x12, 0x06, 0x89, 0x90, 0xA0, 0xBD, 0x51, 0x86, 0x90, 0xA0, 0xBE, 0xF0, 0x51, 0x73, +0x7D, 0x02, 0x7F, 0x38, 0xC1, 0x00, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xB6, +0x74, 0x15, 0xF0, 0x90, 0xA1, 0xC4, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0xB8, 0xEF, 0xF0, 0x7B, 0x01, +0x7A, 0xA1, 0x79, 0xB6, 0xD1, 0xA2, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0xEE, 0x54, 0x40, 0xFE, +0xEF, 0x54, 0xBF, 0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, +0xFD, 0x4F, 0x22, 0xF1, 0x16, 0x7F, 0x04, 0x8F, 0x71, 0x7F, 0x02, 0x12, 0x44, 0xB7, 0x90, 0x9E, +0x92, 0xE0, 0x45, 0x71, 0xF0, 0x22, 0x90, 0xA1, 0x01, 0x02, 0x45, 0xBE, 0x90, 0x05, 0x00, 0x74, +0x1C, 0xF0, 0xA3, 0x22, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F, 0x4E, 0x22, 0xF0, 0xEE, 0x54, 0x08, +0xFE, 0xEF, 0x54, 0xF7, 0x22, 0x7D, 0x03, 0x7F, 0x11, 0xD1, 0x00, 0xEF, 0x22, 0xFE, 0x54, 0x10, +0xFD, 0xEF, 0x54, 0xEF, 0x4D, 0xFF, 0x22, 0xFE, 0x54, 0x20, 0xFD, 0xEF, 0x54, 0xDF, 0x4D, 0xFF, +0x22, 0x90, 0x9F, 0x9E, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22, 0xF0, 0xEE, 0x54, 0x10, +0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x02, 0x06, 0x89, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0x90, +0xA1, 0xD9, 0xF0, 0x90, 0xA0, 0x4C, 0xE0, 0x90, 0xA1, 0xDA, 0x22, 0x7D, 0x01, 0x7F, 0x17, 0xC1, +0x00, 0x90, 0xA0, 0x72, 0x74, 0x05, 0xF0, 0x22, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0x22, 0x90, +0xA0, 0x50, 0xE0, 0xC4, 0x54, 0x0F, 0x20, 0xE0, 0x1D, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x17, 0x90, +0x9E, 0x99, 0xE0, 0xFF, 0x7B, 0x18, 0xE4, 0xFD, 0x12, 0x4D, 0x59, 0x90, 0xA2, 0x30, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0x12, 0x4F, 0x09, 0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x44, 0xDE, +0x90, 0xA0, 0xFC, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x9E, 0x92, 0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0, +0x60, 0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE0, 0x0E, 0x90, 0x9E, 0x92, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, +0xFF, 0x12, 0x79, 0x54, 0x11, 0x5B, 0xD1, 0x2E, 0x30, 0xE1, 0x06, 0x54, 0xFD, 0xF0, 0x12, 0x7E, +0xEF, 0xD1, 0x2E, 0x30, 0xE2, 0x06, 0x54, 0xFB, 0xF0, 0x12, 0xA0, 0xF3, 0xD1, 0x2E, 0x30, 0xE6, +0x06, 0x54, 0xBF, 0xF0, 0x12, 0x97, 0xE7, 0xD2, 0xAF, 0x80, 0xBC, 0xE4, 0xF5, 0x51, 0x90, 0x9F, +0x9C, 0xE0, 0xFF, 0xE5, 0x51, 0xC3, 0x9F, 0x40, 0x02, 0xA1, 0xFB, 0xAF, 0x51, 0x12, 0x5F, 0x2F, +0xEF, 0x70, 0x02, 0xA1, 0xF7, 0x12, 0x51, 0x14, 0x12, 0x56, 0xE5, 0x30, 0xE0, 0x02, 0xA1, 0xF7, +0x90, 0x04, 0xA0, 0xE0, 0xFF, 0xA3, 0xE0, 0xFE, 0xEF, 0x64, 0x01, 0x70, 0x2D, 0xE5, 0x51, 0x6E, +0x70, 0x28, 0xA3, 0xE0, 0xF5, 0x52, 0xA3, 0xE0, 0x90, 0xA1, 0x0C, 0x12, 0x7B, 0x8B, 0xE5, 0x52, +0xF0, 0x75, 0xF0, 0x10, 0x12, 0x78, 0xE8, 0xE0, 0x54, 0xFC, 0xFF, 0x90, 0xA1, 0x0C, 0xE0, 0x12, +0xAD, 0x11, 0xE5, 0x51, 0x12, 0x78, 0xE8, 0xEF, 0xF0, 0x22, 0xE5, 0x51, 0x12, 0x7A, 0xC2, 0xE0, +0xFE, 0xA3, 0xE0, 0xD3, 0x94, 0x00, 0xEE, 0x94, 0x00, 0x50, 0x02, 0xA1, 0xF7, 0xE5, 0x51, 0x75, +0xF0, 0x0A, 0xA4, 0x24, 0x01, 0xF9, 0x74, 0x8D, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x90, 0xA1, 0x00, +0x12, 0x45, 0xBE, 0xE5, 0x51, 0x12, 0x7A, 0xC2, 0xE0, 0xF5, 0x56, 0xA3, 0xE0, 0xF5, 0x57, 0x74, +0x91, 0x25, 0x51, 0x12, 0x7F, 0xD8, 0xE0, 0xFF, 0x90, 0xA1, 0x03, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, +0x90, 0x00, 0x02, 0x12, 0x07, 0xAB, 0xFF, 0xAE, 0xF0, 0x12, 0x07, 0x80, 0x2F, 0xFF, 0xE5, 0xF0, +0x3E, 0xFE, 0x90, 0x00, 0x04, 0xD1, 0x25, 0xFE, 0x90, 0x00, 0x06, 0xD1, 0x25, 0xFE, 0x90, 0x00, +0x08, 0xD1, 0x25, 0x90, 0xA1, 0x05, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x07, 0x80, 0xFF, 0xC3, 0x90, +0xA1, 0x06, 0xE0, 0x9F, 0xFE, 0x90, 0xA1, 0x05, 0xE0, 0x95, 0xF0, 0x90, 0xA1, 0x07, 0xF0, 0xA3, +0xCE, 0xF0, 0x90, 0x00, 0x06, 0x12, 0x07, 0xAB, 0xFD, 0xAC, 0xF0, 0x25, 0xE0, 0xFF, 0xEC, 0x33, +0xFE, 0xEF, 0x2D, 0xFD, 0xEE, 0x3C, 0xFC, 0x90, 0x00, 0x04, 0x12, 0x07, 0xAB, 0x25, 0xE0, 0xFF, +0xE5, 0xF0, 0x33, 0xFE, 0x90, 0x00, 0x02, 0xD1, 0x25, 0xCF, 0x2D, 0xFD, 0xEF, 0x3C, 0xFC, 0xD1, +0x0A, 0x12, 0xAC, 0x5F, 0xAE, 0xF0, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x2D, +0xFF, 0xEC, 0x3E, 0x90, 0xA1, 0x09, 0xF0, 0xA3, 0xEF, 0x12, 0x7B, 0x8B, 0xE0, 0xF5, 0x52, 0x54, +0x7F, 0xF5, 0x53, 0x75, 0xF0, 0x04, 0xE5, 0x51, 0x12, 0x57, 0xEF, 0xE0, 0x90, 0xA1, 0x0B, 0xF0, +0x12, 0x51, 0x14, 0xFF, 0x13, 0x13, 0x54, 0x03, 0x90, 0xA1, 0x0C, 0xF0, 0xB1, 0xFE, 0xE0, 0xC3, +0x94, 0x05, 0x40, 0x02, 0x81, 0x1C, 0x90, 0xA1, 0x0B, 0xE0, 0xFF, 0xE5, 0x53, 0x9F, 0x40, 0x08, +0x8F, 0x53, 0x53, 0x52, 0x80, 0xEF, 0x42, 0x52, 0xE5, 0x53, 0x90, 0x41, 0x5F, 0x93, 0xFF, 0xD1, +0x38, 0xE0, 0xC3, 0x9F, 0xE5, 0x53, 0x40, 0x05, 0x90, 0x41, 0x37, 0x80, 0x03, 0x90, 0x41, 0x4B, +0x93, 0xF5, 0x58, 0x90, 0xA0, 0xA2, 0xE0, 0x60, 0x7D, 0xE5, 0x53, 0x64, 0x13, 0x60, 0x05, 0xE5, +0x53, 0xB4, 0x0B, 0x05, 0x90, 0xA0, 0xA4, 0x80, 0x23, 0xE5, 0x53, 0x64, 0x12, 0x60, 0x05, 0xE5, +0x53, 0xB4, 0x0A, 0x05, 0x90, 0xA0, 0xA5, 0x80, 0x13, 0xE5, 0x53, 0x64, 0x11, 0x60, 0x05, 0xE5, +0x53, 0xB4, 0x09, 0x05, 0x90, 0xA0, 0xA6, 0x80, 0x03, 0x90, 0xA0, 0xA3, 0xE0, 0xF5, 0x5C, 0xE5, +0x5C, 0xC3, 0x94, 0x80, 0x50, 0x28, 0xE5, 0x5C, 0x94, 0x1B, 0x40, 0x02, 0x80, 0x13, 0xE5, 0x58, +0x25, 0x5C, 0xFF, 0xE4, 0x33, 0xFE, 0xD3, 0xEF, 0x94, 0x1B, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x40, +0x05, 0x75, 0x58, 0x1B, 0x80, 0x20, 0xE5, 0x5C, 0x25, 0x58, 0xF5, 0x58, 0x80, 0x18, 0xC3, 0xE4, +0x95, 0x5C, 0xF5, 0x5C, 0xE5, 0x58, 0xD3, 0x95, 0x5C, 0x40, 0x08, 0xE5, 0x58, 0x95, 0x5C, 0xF5, +0x58, 0x80, 0x03, 0xE4, 0xF5, 0x58, 0xE5, 0x58, 0x75, 0xF0, 0x06, 0xA4, 0x24, 0x95, 0xF9, 0x74, +0x40, 0x35, 0xF0, 0xFA, 0x7B, 0xFF, 0x90, 0xA0, 0xFD, 0x12, 0x45, 0xBE, 0xC3, 0xE5, 0x57, 0x94, +0x0F, 0xE5, 0x56, 0x94, 0x00, 0x50, 0x4E, 0xD1, 0x0A, 0x90, 0x00, 0x06, 0x12, 0x07, 0xAB, 0xFF, +0xAE, 0xF0, 0x12, 0xAC, 0x5F, 0x2F, 0xFD, 0xE5, 0xF0, 0x3E, 0xFC, 0xD1, 0x1C, 0xFF, 0xD3, 0xED, +0x9F, 0xEC, 0x9E, 0x40, 0x05, 0x12, 0x7D, 0x5B, 0x61, 0xFD, 0xE5, 0x57, 0xAE, 0x56, 0x78, 0x02, +0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFD, 0xAC, 0x06, 0xD1, 0x1C, 0x2D, 0xFF, 0xEE, 0x3C, +0xFE, 0xD1, 0x0A, 0x12, 0x07, 0x80, 0xD3, 0x9F, 0xE5, 0xF0, 0x9E, 0x50, 0x02, 0x61, 0xFD, 0xAF, +0x51, 0xD1, 0x7A, 0x61, 0xFD, 0xE5, 0x51, 0x70, 0x3D, 0xD1, 0x0A, 0x12, 0xAC, 0x5F, 0xFD, 0xAC, +0xF0, 0xD1, 0x1C, 0xFF, 0xC3, 0xED, 0x9F, 0xEC, 0x9E, 0x50, 0x08, 0x90, 0x9E, 0x91, 0x74, 0x01, +0xF0, 0x80, 0x23, 0xE5, 0x57, 0xAE, 0x56, 0x78, 0x03, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, +0xFB, 0xAA, 0x06, 0xD1, 0x1C, 0x2B, 0xFF, 0xEE, 0x3A, 0xFE, 0xD3, 0xED, 0x9F, 0xEC, 0x9E, 0x40, +0x05, 0xE4, 0x90, 0x9E, 0x91, 0xF0, 0x12, 0xAC, 0x83, 0x40, 0x05, 0x75, 0x59, 0x05, 0x80, 0x13, +0xD3, 0xE5, 0x57, 0x94, 0xC8, 0xE5, 0x56, 0x94, 0x00, 0x40, 0x05, 0x75, 0x59, 0x02, 0x80, 0x03, +0xE4, 0xF5, 0x59, 0xE5, 0x51, 0xD1, 0x6E, 0xE0, 0xF5, 0x54, 0xA3, 0xE0, 0xF5, 0x55, 0xE4, 0xF5, +0x5D, 0xD1, 0x0A, 0x75, 0xF0, 0x02, 0xE5, 0x5D, 0x12, 0xAB, 0xCA, 0x80, 0x05, 0xCE, 0xC3, 0x13, +0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0xA0, 0xFD, 0x12, 0x45, 0xB5, 0x85, 0x5D, 0x82, 0x75, 0x83, +0x00, 0x12, 0x06, 0xA2, 0x12, 0xAB, 0x99, 0x05, 0x5D, 0xE5, 0x5D, 0xB4, 0x05, 0xD3, 0x90, 0xA0, +0xFD, 0x12, 0x45, 0xB5, 0x12, 0x6A, 0x7A, 0xFD, 0x7C, 0x00, 0x12, 0xAD, 0x01, 0x80, 0x05, 0xCE, +0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x12, 0x07, 0x03, 0xD3, 0xE5, 0x55, 0x9F, 0xE5, 0x54, +0x9E, 0x40, 0x0C, 0xE5, 0x55, 0x9F, 0xF5, 0x55, 0xE5, 0x54, 0x9E, 0xF5, 0x54, 0x80, 0x05, 0xE4, +0xF5, 0x54, 0xF5, 0x55, 0xE5, 0x51, 0xD1, 0x6E, 0x12, 0xAD, 0x09, 0xAE, 0x54, 0x12, 0x7C, 0xED, +0xC3, 0x12, 0x45, 0x60, 0x50, 0x06, 0xAF, 0x51, 0xD1, 0x7A, 0x80, 0x12, 0x12, 0xAB, 0x0D, 0xD3, +0x74, 0x01, 0x93, 0x95, 0x55, 0xE4, 0x93, 0x95, 0x54, 0x40, 0x09, 0x12, 0x7D, 0x5B, 0xD1, 0x50, +0xE4, 0xF0, 0x80, 0x29, 0xD1, 0x50, 0xE0, 0x04, 0xF0, 0xD1, 0x50, 0xE0, 0xC3, 0x94, 0x05, 0x40, +0x1C, 0xD1, 0x50, 0xE4, 0xF0, 0x12, 0xAB, 0x0D, 0xE4, 0x93, 0xFE, 0x74, 0x01, 0x93, 0x12, 0x7C, +0xED, 0x12, 0x7F, 0xD0, 0xE5, 0x51, 0xD1, 0x6E, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x51, 0xD1, +0x6E, 0xA3, 0xE0, 0x90, 0xA1, 0x63, 0xF0, 0x90, 0xA1, 0x62, 0xE5, 0x52, 0xF0, 0xAB, 0x51, 0xE4, +0xFD, 0xFF, 0x12, 0x98, 0x28, 0xE4, 0xF5, 0x54, 0xF5, 0x55, 0xA1, 0xDB, 0xB1, 0xFE, 0xE0, 0xFC, +0x64, 0x05, 0x60, 0x02, 0x81, 0xE3, 0xAD, 0x53, 0xAF, 0x51, 0x12, 0xA5, 0x74, 0x12, 0xAC, 0x26, +0xEF, 0xD1, 0x44, 0xE0, 0x54, 0x07, 0xF5, 0x5B, 0xD1, 0x38, 0xE0, 0xFF, 0xC3, 0x94, 0x30, 0x50, +0x06, 0xE4, 0xB1, 0xFC, 0xE4, 0x80, 0x56, 0x12, 0xAC, 0x26, 0xE0, 0x64, 0x01, 0x70, 0x66, 0x12, +0xAB, 0x61, 0xE0, 0x64, 0x0A, 0x60, 0x28, 0xEF, 0x24, 0x05, 0xFF, 0xE4, 0x33, 0xFE, 0x12, 0xAC, +0x1A, 0xE0, 0xFD, 0x12, 0xAB, 0xF0, 0x50, 0x17, 0xED, 0x24, 0x05, 0xFF, 0xE4, 0x33, 0xFE, 0xD1, +0x38, 0xE0, 0x12, 0xAB, 0xF0, 0x50, 0x08, 0x12, 0xAB, 0x81, 0xE0, 0x65, 0x53, 0x60, 0x2A, 0xE5, 0x5B, 0x70, 0x05, 0x75, 0x5B, 0x01, 0x80, 0x0D, 0xE5, 0x5B, 0xB4, 0x01, 0x05, 0x75, 0x5B, 0x03, -0x80, 0x03, 0x75, 0x5B, 0x05, 0xB1, 0x97, 0xE0, 0xFF, 0xF1, 0xBD, 0xEF, 0xF0, 0x74, 0x92, 0x25, -0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9A, 0x80, 0x17, 0xB1, 0x8A, 0xE4, 0xF0, 0xF1, 0x60, 0xE0, 0x04, -0xF0, 0x80, 0x10, 0xE4, 0xF5, 0x5B, 0x74, 0x92, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9B, 0xF5, -0x83, 0xE4, 0xF0, 0xF1, 0xA5, 0xE5, 0x53, 0xF0, 0x12, 0x51, 0x02, 0xC4, 0x13, 0x13, 0x54, 0x03, -0x20, 0xE0, 0x02, 0xA1, 0x50, 0xF1, 0x60, 0xE4, 0xF0, 0xB1, 0x88, 0xE4, 0xF0, 0xA1, 0x50, 0xEC, -0x64, 0x06, 0x60, 0x02, 0xA1, 0x60, 0xF5, 0x54, 0xF5, 0x55, 0xB1, 0xD2, 0xE0, 0x54, 0x07, 0xF5, -0x5B, 0xF1, 0x85, 0x40, 0x05, 0x75, 0x59, 0x05, 0x80, 0x13, 0xD3, 0xE5, 0x57, 0x94, 0xFA, 0xE5, -0x56, 0x94, 0x00, 0x40, 0x05, 0x75, 0x59, 0x02, 0x80, 0x03, 0xE4, 0xF5, 0x59, 0xF1, 0x74, 0x80, -0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0x42, 0x24, 0xE4, 0x93, 0xFD, 0x7C, -0x00, 0x12, 0x07, 0x03, 0x90, 0xA0, 0xFB, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xF5, 0x5A, 0xB1, -0xA3, 0x75, 0xF0, 0x02, 0xE5, 0x5A, 0x12, 0xA9, 0x5E, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, -0xD8, 0xF9, 0xFF, 0xE5, 0x5A, 0x90, 0x42, 0x1F, 0x93, 0x12, 0xA9, 0x3E, 0xC3, 0x90, 0xA0, 0xFC, -0xE0, 0x95, 0x55, 0x90, 0xA0, 0xFB, 0xE0, 0x95, 0x54, 0x40, 0x07, 0x05, 0x5A, 0xE5, 0x5A, 0xB4, -0x05, 0xCD, 0xE5, 0x5A, 0xC3, 0x13, 0xF5, 0x5A, 0xE5, 0x5B, 0x24, 0x01, 0x12, 0xA2, 0xF3, 0xFF, -0xD3, 0x95, 0x5A, 0x40, 0x06, 0xEF, 0x95, 0x5A, 0xFF, 0x80, 0x02, 0xE4, 0xFF, 0xB1, 0xA9, 0xE0, -0xC3, 0x13, 0xFE, 0xEF, 0xC4, 0x33, 0x54, 0xE0, 0x2E, 0x04, 0xFE, 0xB1, 0xA9, 0xEE, 0xF0, 0xB1, -0xA9, 0xE0, 0xC3, 0x94, 0xC0, 0x40, 0x05, 0xB1, 0xA9, 0x74, 0xC0, 0xF0, 0xB1, 0xA9, 0x12, 0x4F, -0xD2, 0x25, 0xE0, 0xFF, 0x70, 0x04, 0xF5, 0x5B, 0x80, 0x04, 0xEF, 0x14, 0xF5, 0x5B, 0xD3, 0x90, -0xA0, 0xF1, 0xE0, 0x94, 0x03, 0x90, 0xA0, 0xF0, 0xE0, 0x94, 0x00, 0x40, 0x03, 0xE4, 0xF5, 0x5B, -0xB1, 0xD2, 0xE0, 0x54, 0xF8, 0x90, 0xA0, 0xFD, 0xF0, 0x45, 0x5B, 0xFF, 0xB1, 0xD1, 0xEF, 0xF0, -0xB1, 0x8A, 0xE0, 0xD3, 0x94, 0x05, 0x74, 0x92, 0x50, 0x07, 0xB1, 0x8C, 0xE0, 0x04, 0xF0, 0x80, -0x04, 0xB1, 0x8C, 0xE4, 0xF0, 0xE4, 0xFD, 0xAF, 0x51, 0x12, 0xA2, 0xFC, 0x05, 0x51, 0xE5, 0x51, -0xC3, 0x94, 0x80, 0x50, 0x02, 0x01, 0x33, 0x22, 0xF5, 0x5B, 0x74, 0x92, 0x25, 0x51, 0xF5, 0x82, -0xE4, 0x34, 0x9B, 0xF5, 0x83, 0x22, 0xFF, 0x74, 0x92, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x99, -0xF5, 0x83, 0x22, 0x90, 0xA0, 0xED, 0x02, 0x45, 0xB5, 0x74, 0x01, 0x25, 0x51, 0xF5, 0x82, 0xE4, -0x34, 0x93, 0xF5, 0x83, 0x22, 0xE5, 0x56, 0xC3, 0x13, 0xFE, 0xE5, 0x57, 0x13, 0x22, 0x12, 0x07, -0xAB, 0x2F, 0xFF, 0xEE, 0x35, 0xF0, 0x22, 0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x9D, 0x93, 0xE0, 0xFF, -0x22, 0xF0, 0x75, 0xF0, 0x10, 0xE5, 0x51, 0x90, 0x81, 0x01, 0x02, 0x45, 0xA9, 0xD3, 0x10, 0xAF, -0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x67, 0x8D, 0x68, 0x8B, 0x69, 0xE4, 0x90, 0xA1, 0xAA, 0xF0, 0xE5, -0x67, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x90, 0xA1, 0xA5, 0xF0, 0xE5, 0x67, 0x54, 0x07, 0x90, 0xA1, -0xA7, 0xF0, 0x75, 0xF0, 0x10, 0xEF, 0xB1, 0xD7, 0xE0, 0x90, 0xA1, 0xA8, 0xF1, 0x8F, 0xE0, 0x54, -0x7F, 0x90, 0xA1, 0xAB, 0xF0, 0x75, 0xF0, 0x04, 0xE5, 0x67, 0x12, 0x56, 0xC6, 0xE0, 0x90, 0xA1, -0xAC, 0xF0, 0xF1, 0x7C, 0xE5, 0x69, 0x70, 0x24, 0xE0, 0xFB, 0xF1, 0xB1, 0xE4, 0x93, 0xFE, 0x74, -0x01, 0x93, 0xFF, 0xE4, 0xFC, 0xFD, 0xEB, 0xF1, 0xE3, 0x12, 0x45, 0x39, 0x78, 0x01, 0x12, 0x08, -0x47, 0xE5, 0x67, 0xF1, 0x50, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA1, 0xAB, 0xE0, -0xFF, 0x90, 0xA1, 0xA6, 0xE0, 0xFE, 0xD3, 0x9F, 0x40, 0x0B, 0xE5, 0x68, 0x54, 0x80, 0xFD, 0xEF, -0x4D, 0xF5, 0x68, 0x80, 0x0C, 0x90, 0xA1, 0xAC, 0xE0, 0xFF, 0xEE, 0xC3, 0x9F, 0x50, 0x02, 0x8F, -0x68, 0xF1, 0x7C, 0xE5, 0x68, 0x54, 0x80, 0x90, 0xA1, 0xA9, 0xF0, 0xE5, 0x69, 0x70, 0x2A, 0x90, -0xA1, 0xA5, 0xE0, 0x24, 0x81, 0xF1, 0x6C, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0xA1, 0xA7, -0x12, 0xA9, 0x1B, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0xD0, 0x82, 0xD0, 0x83, 0xF0, -0x90, 0xA1, 0xA8, 0xE0, 0x54, 0x7F, 0xF0, 0x80, 0x45, 0x90, 0xA1, 0xA5, 0xE0, 0x24, 0x81, 0xF1, -0x6C, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0xA1, 0xA7, 0x12, 0xA9, 0x1B, 0x80, 0x02, 0xC3, -0x33, 0xD8, 0xFC, 0x4F, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x75, 0xF0, 0x10, 0xE5, 0x67, 0xB1, 0xD7, -0xE0, 0x54, 0x07, 0xFF, 0x90, 0xA1, 0xA8, 0xF0, 0x90, 0xA1, 0xA6, 0xE0, 0x90, 0x41, 0xF7, 0x93, -0xFE, 0x33, 0x33, 0x33, 0x54, 0xF8, 0x4F, 0x90, 0xA1, 0xA8, 0xF0, 0x44, 0x80, 0xF0, 0x75, 0xF0, -0x10, 0xE5, 0x67, 0x90, 0x81, 0x00, 0x12, 0x45, 0xA9, 0xE5, 0x68, 0xF0, 0xE5, 0x67, 0x70, 0x06, -0x90, 0x01, 0xC8, 0xE5, 0x68, 0xF0, 0x90, 0xA1, 0xA8, 0xE0, 0xFF, 0x75, 0xF0, 0x10, 0xE5, 0x67, -0xB1, 0xD7, 0xEF, 0xF0, 0x75, 0xF0, 0x10, 0xE5, 0x67, 0x12, 0x7A, 0x7D, 0x54, 0xFC, 0xFF, 0xE5, -0x6A, 0x54, 0x03, 0x4F, 0xFF, 0x75, 0xF0, 0x10, 0xE5, 0x67, 0x90, 0x81, 0x05, 0x12, 0x45, 0xA9, -0xEF, 0xF0, 0x7D, 0x01, 0xAF, 0x67, 0x12, 0xA2, 0xFC, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE9, 0x25, -0xE0, 0x25, 0xE0, 0x24, 0x73, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x12, 0x45, 0x7D, 0xEB, -0x25, 0xE0, 0x24, 0x91, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0x22, 0x90, 0x00, 0x08, 0x02, 0x07, 0xAB, -0x74, 0x92, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9A, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, 0x34, -0x94, 0xF5, 0x83, 0x22, 0xE5, 0x57, 0xAE, 0x56, 0xA8, 0x59, 0x08, 0x22, 0xE5, 0x68, 0x54, 0x7F, -0x90, 0xA1, 0xA6, 0xF0, 0x22, 0xD3, 0xE5, 0x57, 0x94, 0xE8, 0xE5, 0x56, 0x94, 0x03, 0x22, 0xF0, -0x75, 0xF0, 0x04, 0xEF, 0x90, 0x96, 0x12, 0x02, 0x45, 0xA9, 0xE0, 0xD3, 0x9F, 0xEE, 0x64, 0x80, -0xF8, 0x74, 0x80, 0x98, 0x22, 0x74, 0x12, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9C, 0xF5, 0x83, -0x22, 0x25, 0xE0, 0x24, 0xC3, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x22, 0x74, 0x01, 0x25, -0x51, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0x74, 0x12, 0x25, 0x51, 0xF5, 0x82, 0xE4, -0x34, 0x9A, 0xF5, 0x83, 0x22, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x92, -0xF5, 0x83, 0x22, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x73, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, -0x02, 0x45, 0x99, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, -0xC0, 0x07, 0x7D, 0xF3, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x77, 0x11, 0x1A, 0xD0, 0x07, 0xD0, -0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xFF, 0xA3, 0xF0, 0xED, 0x04, 0x90, -0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, -0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, 0x27, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x78, 0x11, -0x1A, 0xD0, 0x07, 0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, +0x80, 0x03, 0x75, 0x5B, 0x05, 0xD1, 0x38, 0xE0, 0xFF, 0x12, 0xAC, 0x1A, 0xEF, 0xF0, 0x74, 0x11, +0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9B, 0x80, 0x18, 0xB1, 0xFE, 0xE4, 0xF0, 0x12, 0xAB, 0x61, +0xE0, 0x04, 0xF0, 0x80, 0x10, 0xE4, 0xF5, 0x5B, 0x74, 0x11, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, +0x9C, 0xF5, 0x83, 0xE4, 0xF0, 0x12, 0xAB, 0x81, 0xE5, 0x53, 0xF0, 0x12, 0x51, 0x14, 0xC4, 0x13, +0x13, 0x54, 0x03, 0x20, 0xE0, 0x02, 0xA1, 0xCB, 0x12, 0xAB, 0x61, 0xE4, 0xF0, 0xB1, 0xFC, 0xE4, +0xF0, 0xA1, 0xCB, 0xEC, 0x64, 0x06, 0x60, 0x02, 0xA1, 0xDB, 0xF5, 0x54, 0xF5, 0x55, 0xD1, 0x45, +0xE0, 0x54, 0x07, 0xF5, 0x5B, 0x12, 0xAC, 0x83, 0x40, 0x05, 0x75, 0x59, 0x05, 0x80, 0x13, 0xD3, +0xE5, 0x57, 0x94, 0xFA, 0xE5, 0x56, 0x94, 0x00, 0x40, 0x05, 0x75, 0x59, 0x02, 0x80, 0x03, 0xE4, +0xF5, 0x59, 0x12, 0xAD, 0x01, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, +0x42, 0x24, 0xE4, 0x93, 0xFD, 0x7C, 0x00, 0x12, 0x07, 0x03, 0x90, 0xA1, 0x0E, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0xE4, 0xF5, 0x5A, 0xD1, 0x0A, 0x75, 0xF0, 0x02, 0xE5, 0x5A, 0x12, 0xAB, 0xCA, 0x80, +0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0xE5, 0x5A, 0x90, 0x42, 0x1F, 0x93, 0x12, +0xAB, 0x99, 0xC3, 0x90, 0xA1, 0x0F, 0xE0, 0x95, 0x55, 0x90, 0xA1, 0x0E, 0xE0, 0x95, 0x54, 0x40, +0x07, 0x05, 0x5A, 0xE5, 0x5A, 0xB4, 0x05, 0xCD, 0xE5, 0x5A, 0xC3, 0x13, 0xF5, 0x5A, 0xE5, 0x5B, +0x24, 0x01, 0xFF, 0xE4, 0x33, 0xA2, 0xE7, 0x13, 0xEF, 0x13, 0xFF, 0xD3, 0x95, 0x5A, 0x40, 0x06, +0xEF, 0x95, 0x5A, 0xFF, 0x80, 0x02, 0xE4, 0xFF, 0xD1, 0x10, 0xE0, 0xC3, 0x13, 0xFE, 0xEF, 0xC4, +0x33, 0x54, 0xE0, 0x2E, 0x04, 0xFE, 0xD1, 0x10, 0xEE, 0xF0, 0xD1, 0x10, 0xE0, 0xC3, 0x94, 0xC0, +0x40, 0x05, 0xD1, 0x10, 0x74, 0xC0, 0xF0, 0xD1, 0x10, 0x12, 0x4F, 0xD3, 0x25, 0xE0, 0xFF, 0x70, +0x04, 0xF5, 0x5B, 0x80, 0x04, 0xEF, 0x14, 0xF5, 0x5B, 0xD3, 0x90, 0xA1, 0x04, 0xE0, 0x94, 0x03, +0x90, 0xA1, 0x03, 0xE0, 0x94, 0x00, 0x40, 0x03, 0xE4, 0xF5, 0x5B, 0xD1, 0x45, 0xE0, 0x54, 0xF8, +0x90, 0xA1, 0x10, 0xF0, 0x45, 0x5B, 0xFF, 0xD1, 0x44, 0xEF, 0xF0, 0xB1, 0xFE, 0xE0, 0xD3, 0x94, +0x05, 0x74, 0x11, 0x50, 0x07, 0xD1, 0x00, 0xE0, 0x04, 0xF0, 0x80, 0x04, 0xD1, 0x00, 0xE4, 0xF0, +0xE4, 0xFD, 0xAF, 0x51, 0x12, 0x78, 0xFC, 0x05, 0x51, 0x01, 0x5E, 0x22, 0xF5, 0x5B, 0x74, 0x11, +0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9C, 0xF5, 0x83, 0x22, 0x90, 0xA1, 0x00, 0x02, 0x45, 0xB5, +0x74, 0x01, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0x22, 0xE5, 0x56, 0xC3, 0x13, +0xFE, 0xE5, 0x57, 0x13, 0x22, 0x12, 0x07, 0xAB, 0x2F, 0xFF, 0xEE, 0x35, 0xF0, 0x22, 0xD2, 0xAF, +0xC2, 0xAF, 0x90, 0x9E, 0x92, 0xE0, 0xFF, 0x22, 0x74, 0x11, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, +0x9A, 0xF5, 0x83, 0x22, 0xF0, 0x75, 0xF0, 0x10, 0xE5, 0x51, 0x90, 0x81, 0x01, 0x02, 0x45, 0xA9, +0x74, 0x11, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x98, 0xF5, 0x83, 0x22, 0xE9, 0x25, 0xE0, 0x25, +0xE0, 0x24, 0x73, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x12, 0x45, 0x7D, 0xEB, 0x25, 0xE0, +0x24, 0x91, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0xAB, 0x07, 0x75, 0xF0, 0x10, 0xEB, +0x12, 0x7B, 0x91, 0xE0, 0xF5, 0x5E, 0xE4, 0xF5, 0x62, 0xE5, 0x5E, 0x54, 0x7F, 0xF9, 0xE5, 0x5E, +0x54, 0x80, 0xFA, 0x75, 0xF0, 0x04, 0xEB, 0x12, 0x57, 0xEF, 0xE0, 0xF5, 0x60, 0x75, 0xF0, 0x04, +0xEB, 0x12, 0x51, 0x19, 0xFF, 0xC4, 0x54, 0x03, 0xF5, 0x61, 0xD1, 0x5C, 0xEE, 0xF0, 0xA3, 0xEF, +0xF0, 0xE5, 0x5E, 0x4A, 0xFF, 0x74, 0x91, 0x2B, 0x12, 0x7D, 0x53, 0xEF, 0xF0, 0x75, 0xF0, 0x04, +0xEB, 0x12, 0x51, 0x19, 0x13, 0x13, 0x54, 0x03, 0xF5, 0x5F, 0x74, 0x91, 0x2B, 0x12, 0xAC, 0x54, +0xE9, 0x64, 0x2C, 0x70, 0x2A, 0x75, 0xF0, 0x04, 0xEB, 0x12, 0x51, 0x19, 0xFF, 0x54, 0x03, 0xFE, +0xE5, 0x5F, 0xC3, 0x9E, 0x50, 0x19, 0x05, 0x5F, 0x12, 0x7E, 0x8D, 0xFE, 0x75, 0xF0, 0x04, 0xEB, +0x90, 0x96, 0x14, 0x12, 0x45, 0xA9, 0xEF, 0x54, 0xF3, 0x4E, 0xF0, 0x89, 0x5E, 0xE1, 0x80, 0xE9, +0xC3, 0x95, 0x60, 0x50, 0x48, 0xE9, 0x04, 0xFD, 0xED, 0xD3, 0x95, 0x60, 0x50, 0x72, 0xED, 0x12, +0xAC, 0x97, 0xEB, 0x12, 0x55, 0x2D, 0xE0, 0xF5, 0x82, 0x75, 0x83, 0x00, 0xED, 0x54, 0x07, 0x12, +0x7C, 0xC6, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x12, 0xAC, 0x8D, 0x60, +0x19, 0xB9, 0x13, 0x10, 0x79, 0x18, 0x89, 0x5E, 0x74, 0x91, 0x2B, 0x12, 0x56, 0x59, 0xE0, 0x44, +0x04, 0xF0, 0x80, 0x3C, 0xA9, 0x05, 0x89, 0x5E, 0x80, 0x36, 0x0D, 0x80, 0xBB, 0xE9, 0x65, 0x60, +0x70, 0x23, 0x75, 0xF0, 0x04, 0xEB, 0x12, 0x56, 0x3C, 0xFF, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, +0x0C, 0xE5, 0x5E, 0x20, 0xE7, 0x07, 0xE9, 0x44, 0x80, 0xF5, 0x5E, 0x80, 0x13, 0xD1, 0x5C, 0xEE, +0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x74, 0x91, 0x2B, 0x12, 0x7D, 0x53, 0xE5, 0x60, 0xF0, 0xF5, 0x5E, +0xAF, 0x03, 0x85, 0x5F, 0x6A, 0x7B, 0x01, 0xAD, 0x5E, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x8F, 0x67, 0x8D, 0x68, 0x8B, 0x69, 0xE4, 0x90, 0xA1, 0xD2, 0xF0, 0xE5, 0x67, 0x13, 0x13, 0x13, +0x54, 0x1F, 0x90, 0xA1, 0xCD, 0xF0, 0xE5, 0x67, 0x54, 0x07, 0x90, 0xA1, 0xCF, 0xF0, 0x75, 0xF0, +0x10, 0xEF, 0xD1, 0x4A, 0xE0, 0x90, 0xA1, 0xD0, 0x12, 0x57, 0xEA, 0xE0, 0x54, 0x7F, 0x90, 0xA1, +0xD3, 0xF0, 0x75, 0xF0, 0x04, 0xE5, 0x67, 0x12, 0x56, 0xF1, 0xE0, 0x90, 0xA1, 0xD4, 0xF0, 0x12, +0x7C, 0xE4, 0xE5, 0x69, 0x70, 0x1F, 0xE0, 0xFB, 0x12, 0xAB, 0x0F, 0xE4, 0x93, 0xFE, 0x74, 0x01, +0x93, 0xFF, 0xE4, 0xFC, 0xFD, 0xEB, 0x12, 0x7C, 0xF3, 0x12, 0x7F, 0xD0, 0xE5, 0x67, 0xD1, 0x6E, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA1, 0xD3, 0xE0, 0xFF, 0x90, 0xA1, 0xCE, 0xE0, 0xFE, 0xD3, +0x9F, 0x40, 0x0B, 0xE5, 0x68, 0x54, 0x80, 0xFD, 0xEF, 0x4D, 0xF5, 0x68, 0x80, 0x0C, 0x90, 0xA1, +0xD4, 0xE0, 0xFF, 0xEE, 0xC3, 0x9F, 0x50, 0x02, 0x8F, 0x68, 0x91, 0xE4, 0xE5, 0x68, 0x54, 0x80, +0x90, 0xA1, 0xD1, 0xF0, 0xE5, 0x69, 0x70, 0x29, 0x90, 0xA1, 0xCD, 0xE0, 0x24, 0x81, 0x11, 0xDA, +0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0xA1, 0xCF, 0x11, 0xF4, 0x80, 0x02, 0xC3, 0x33, 0xD8, +0xFC, 0xF4, 0x5F, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x90, 0xA1, 0xD0, 0xE0, 0x54, 0x7F, 0xF0, 0x80, +0x45, 0x90, 0xA1, 0xCD, 0xE0, 0x24, 0x81, 0x11, 0xDA, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, +0xA1, 0xCF, 0x11, 0xF4, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0xD0, 0x82, 0xD0, 0x83, 0xF0, +0x75, 0xF0, 0x10, 0xE5, 0x67, 0x12, 0x76, 0x4A, 0xE0, 0x54, 0x07, 0xFF, 0x90, 0xA1, 0xD0, 0xF0, +0x90, 0xA1, 0xCE, 0xE0, 0x90, 0x41, 0xF7, 0x93, 0xFE, 0x33, 0x33, 0x33, 0x54, 0xF8, 0x4F, 0x90, +0xA1, 0xD0, 0xF0, 0x44, 0x80, 0xF0, 0x75, 0xF0, 0x10, 0xE5, 0x67, 0x71, 0x91, 0xE5, 0x68, 0xF0, +0xE5, 0x67, 0x70, 0x06, 0x90, 0x01, 0xC8, 0xE5, 0x68, 0xF0, 0x90, 0xA1, 0xD0, 0xE0, 0xFF, 0x75, +0xF0, 0x10, 0xE5, 0x67, 0x12, 0x76, 0x4A, 0xEF, 0xF0, 0x75, 0xF0, 0x10, 0xE5, 0x67, 0x11, 0xE8, +0xE0, 0x54, 0xFC, 0xFF, 0xE5, 0x6A, 0x12, 0xAD, 0x11, 0xE5, 0x67, 0x11, 0xE8, 0xEF, 0xF0, 0x7D, +0x01, 0xAF, 0x67, 0x11, 0xFC, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, +0x83, 0x22, 0x8F, 0x57, 0x75, 0xF0, 0x10, 0xEF, 0x90, 0x81, 0x05, 0x02, 0x45, 0xA9, 0x75, 0xF0, +0x03, 0x12, 0x45, 0xA9, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0xED, 0x60, 0x27, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x8D, 0x01, 0x31, 0x3E, 0x90, +0x8D, 0x03, 0x31, 0x3E, 0x90, 0x8D, 0x05, 0x31, 0x3E, 0x90, 0x8D, 0x07, 0x31, 0x3E, 0x90, 0x8D, +0x09, 0x12, 0x45, 0xA9, 0xE4, 0xF0, 0xA3, 0x51, 0xC0, 0x12, 0xAB, 0xAA, 0xF0, 0x31, 0x4A, 0xE0, +0x54, 0xBF, 0x44, 0x80, 0xFE, 0x31, 0x4A, 0xEE, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x45, +0xA9, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x22, 0x75, 0xF0, 0x10, 0xEF, 0x90, 0x81, +0x03, 0x02, 0x45, 0xA9, 0x90, 0xA1, 0x4A, 0xEF, 0xF0, 0x7E, 0x00, 0x7F, 0x10, 0x7D, 0x00, 0x7B, +0x01, 0x7A, 0xA1, 0x79, 0x4C, 0x12, 0x08, 0xAA, 0x90, 0x9F, 0x9C, 0xE0, 0x90, 0xA1, 0x5E, 0xF0, +0xE4, 0x90, 0xA1, 0x4B, 0xF0, 0x90, 0xA1, 0x5E, 0xE0, 0xFE, 0x90, 0xA1, 0x4B, 0xE0, 0xFD, 0xC3, +0x9E, 0x50, 0x40, 0xED, 0x51, 0xAA, 0xED, 0x54, 0x07, 0xA3, 0xF0, 0x75, 0xF0, 0x10, 0xED, 0x31, +0x4E, 0xE0, 0x30, 0xE7, 0x09, 0x74, 0x81, 0x2D, 0x51, 0x90, 0xE4, 0xF0, 0x80, 0x1D, 0xAF, 0x05, +0x91, 0xDD, 0x51, 0xCE, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0xA1, 0x5D, 0x11, 0xF4, 0x80, +0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x90, 0xA1, 0x4B, 0xE0, 0x04, +0xF0, 0x80, 0xB2, 0x7F, 0x0C, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0xE4, 0x90, 0xA1, 0x4B, 0xF0, 0x90, +0xA1, 0x5E, 0xE0, 0xFF, 0x90, 0xA1, 0x4B, 0xE0, 0xFE, 0xC3, 0x9F, 0x40, 0x02, 0x41, 0x89, 0xEE, +0x51, 0xAA, 0xEE, 0x54, 0x07, 0xA3, 0xF0, 0x91, 0xC5, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0x4E, 0x7F, 0x00, 0x70, 0x02, 0x7F, 0x01, 0x51, 0xCE, 0xE0, 0x5F, 0x60, 0x02, +0x41, 0x81, 0x51, 0x98, 0x90, 0x81, 0x06, 0x51, 0xA1, 0xEF, 0x90, 0x81, 0x07, 0x51, 0xB4, 0xFC, +0x51, 0xC2, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0xF0, 0x10, 0xEC, 0x90, 0x81, 0x0A, 0x51, 0xA1, +0xEC, 0x90, 0x81, 0x0B, 0x51, 0xB4, 0x75, 0xF0, 0x0A, 0x51, 0x8A, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, +0x7F, 0x01, 0x90, 0xA1, 0x4B, 0xE0, 0xFE, 0x75, 0xF0, 0x10, 0x90, 0x81, 0x0B, 0x12, 0x55, 0x30, +0xE0, 0xFD, 0x75, 0xF0, 0x0A, 0xEE, 0x51, 0x8A, 0x75, 0xF0, 0x02, 0xEF, 0x12, 0x45, 0xA9, 0xE4, +0xF0, 0xA3, 0xED, 0xF0, 0x0F, 0xEF, 0xB4, 0x05, 0xD9, 0x51, 0x98, 0x90, 0x81, 0x09, 0x12, 0x45, +0xA9, 0xE0, 0xFE, 0x74, 0x91, 0x2F, 0xF1, 0xD8, 0xEE, 0xF0, 0x90, 0xA1, 0x4B, 0xE0, 0xFF, 0x90, +0xA1, 0x4A, 0xE0, 0xFD, 0x11, 0xFC, 0x90, 0xA1, 0x4B, 0xE0, 0x24, 0x81, 0x51, 0x90, 0x74, 0x01, +0xF0, 0x90, 0xA1, 0x4B, 0xE0, 0x04, 0xF0, 0x21, 0xCF, 0x22, 0x90, 0x8D, 0x01, 0x02, 0x45, 0xA9, +0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0x22, 0x90, 0xA1, 0x4B, 0xE0, 0xFF, 0x75, 0xF0, 0x10, +0x22, 0x12, 0x45, 0xA9, 0xE0, 0xFD, 0x75, 0xF0, 0x10, 0x22, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x90, +0xA1, 0x5C, 0xF0, 0x22, 0x12, 0x45, 0xA9, 0xE0, 0xFE, 0xED, 0xFF, 0x90, 0xA1, 0x4B, 0xE0, 0x22, +0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, 0x90, 0xA1, +0x5C, 0xE0, 0x24, 0x4C, 0xF5, 0x82, 0xE4, 0x34, 0xA1, 0xF5, 0x83, 0x22, 0xE4, 0xF5, 0x63, 0x90, +0x9F, 0x9C, 0xE0, 0xFF, 0xE5, 0x63, 0xC3, 0x9F, 0x40, 0x02, 0x61, 0x8A, 0xAF, 0x63, 0x12, 0x5F, +0x2F, 0xEF, 0x70, 0x02, 0x61, 0x86, 0xE5, 0x63, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0xE5, 0x63, +0x54, 0x07, 0xFE, 0x74, 0x81, 0x2F, 0x11, 0xDA, 0xE0, 0xFD, 0xAF, 0x06, 0x91, 0xC7, 0x08, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x60, 0x69, 0x75, 0xF0, 0x10, +0xE5, 0x63, 0x12, 0x76, 0x4A, 0xE0, 0x20, 0xE7, 0x02, 0x80, 0x10, 0x75, 0xF0, 0x10, 0xE5, 0x63, +0x90, 0x81, 0x02, 0x12, 0x45, 0xA9, 0xE0, 0xFF, 0x20, 0xE7, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, +0x20, 0xF0, 0x80, 0x42, 0xEF, 0x30, 0xE6, 0x12, 0x75, 0xF0, 0x10, 0xE5, 0x63, 0x71, 0x91, 0x71, +0xAA, 0x12, 0x51, 0x19, 0x71, 0xA3, 0xE4, 0xFB, 0x80, 0x27, 0x71, 0x97, 0xE0, 0x04, 0xF0, 0x71, +0x97, 0xE0, 0xD3, 0x94, 0x01, 0x40, 0x0A, 0xAF, 0x63, 0xB1, 0x03, 0x71, 0x97, 0xE4, 0xF0, 0x80, +0x15, 0x75, 0xF0, 0x10, 0xE5, 0x63, 0x71, 0x91, 0x71, 0xAA, 0x12, 0x51, 0x19, 0x71, 0xA3, 0x7B, +0x01, 0xAF, 0x63, 0x12, 0x77, 0x89, 0x05, 0x63, 0x41, 0xDF, 0x22, 0xF0, 0x75, 0xF0, 0x10, 0xE5, +0x51, 0x90, 0x81, 0x00, 0x02, 0x45, 0xA9, 0x74, 0x11, 0x25, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x9D, +0xF5, 0x83, 0x22, 0x13, 0x13, 0x54, 0x03, 0xF5, 0x6A, 0x22, 0xE0, 0xFD, 0x75, 0xF0, 0x04, 0xE5, +0x63, 0x22, 0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0xA2, 0x26, 0xF0, 0x90, 0xA2, 0x26, 0xE0, +0xFD, 0x70, 0x02, 0x81, 0xBB, 0x90, 0x9E, 0xEF, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, +0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x9E, 0xF0, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, +0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0xA2, 0x1B, +0x91, 0xC5, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, +0x02, 0x81, 0x9E, 0xE4, 0x90, 0xA2, 0x27, 0xF0, 0x90, 0xA2, 0x27, 0xE0, 0xF9, 0xC3, 0x94, 0x04, +0x50, 0x41, 0x91, 0xBD, 0xA4, 0xFF, 0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, +0x74, 0xD0, 0x91, 0xCE, 0xF1, 0x49, 0xE5, 0x82, 0x29, 0x12, 0x55, 0x36, 0xEF, 0x91, 0xBC, 0xA4, +0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xF0, 0x91, 0xCE, 0x75, 0xF0, 0x08, 0x90, 0x9E, 0xA3, +0x12, 0x45, 0xA9, 0xE5, 0x82, 0x29, 0x12, 0x55, 0x36, 0xEF, 0xF0, 0x90, 0xA2, 0x27, 0xE0, 0x04, +0xF0, 0x80, 0xB5, 0x90, 0xA2, 0x26, 0xE0, 0xFF, 0x90, 0xA2, 0x1B, 0x11, 0xF4, 0x80, 0x02, 0xC3, +0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0xA2, 0x26, 0xF0, 0x90, 0xA2, 0x1B, 0xE0, 0xFF, 0x74, 0x01, +0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0xA2, 0x1B, +0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0x90, 0x9E, 0xF0, 0x12, 0x6F, 0xD8, 0xB4, 0x0A, 0x02, +0x7F, 0x01, 0xEF, 0x70, 0x02, 0x61, 0xBC, 0xE4, 0x90, 0x9E, 0xF0, 0xF0, 0x61, 0xBC, 0x90, 0x01, +0xC0, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0xA2, 0x1B, 0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A, 0x91, 0xBC, +0x90, 0x01, 0xD0, 0x12, 0x45, 0xA9, 0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, 0xF0, 0x90, 0xA2, 0x1B, +0xE0, 0x75, 0xF0, 0x04, 0x22, 0xE0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x22, 0x2F, 0xF5, +0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x9E, 0xF0, 0xE0, 0x22, 0x31, 0x4A, 0xE0, +0x44, 0x40, 0xF0, 0x22, 0xE5, 0x68, 0x54, 0x7F, 0x90, 0xA1, 0xCE, 0xF0, 0x22, 0xFF, 0xE4, 0xFC, +0xFD, 0xE5, 0x53, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x73, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, +0x02, 0x45, 0x99, 0x75, 0xF0, 0x04, 0xEF, 0x12, 0x51, 0x19, 0xFE, 0x13, 0x13, 0x54, 0x03, 0xFC, +0x12, 0x57, 0xEB, 0xE0, 0xFB, 0xB1, 0x50, 0xE0, 0x54, 0x7F, 0xFD, 0x64, 0x2C, 0x70, 0x1C, 0xEE, +0x54, 0x03, 0xFE, 0xEC, 0xD3, 0x9E, 0x50, 0x13, 0xEC, 0x60, 0x10, 0x1C, 0xEC, 0xD1, 0x8F, 0xFE, +0x75, 0xF0, 0x04, 0xEF, 0x12, 0x51, 0x19, 0x54, 0xF3, 0x4E, 0xF0, 0xED, 0xD3, 0x9B, 0x40, 0x02, +0xAD, 0x03, 0xB1, 0x50, 0xE0, 0x54, 0x80, 0x42, 0x05, 0x8C, 0x6A, 0xE4, 0xFB, 0x02, 0x77, 0x89, +0x74, 0x91, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x9D, 0xF5, 0x83, 0x22, 0x7D, 0x01, 0xAF, 0x51, 0xAA, +0x07, 0xAB, 0x05, 0x75, 0xF0, 0x10, 0xEA, 0x71, 0x91, 0xE0, 0xF5, 0x5E, 0x54, 0x7F, 0xF5, 0x60, +0x75, 0xF0, 0x04, 0xEA, 0x12, 0x56, 0xF1, 0xE0, 0x90, 0xA1, 0x13, 0xF0, 0x75, 0xF0, 0x04, 0xEA, +0x12, 0x57, 0xEF, 0xE0, 0xFF, 0x75, 0xF0, 0x04, 0xEA, 0x12, 0x51, 0x19, 0x13, 0x13, 0x54, 0x03, +0xF5, 0x5F, 0xE5, 0x60, 0x12, 0xAB, 0x0F, 0xE4, 0x93, 0xFC, 0x74, 0x01, 0x93, 0xFD, 0xEA, 0x12, +0x76, 0x6E, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x75, 0xF0, 0x04, 0xEA, 0x12, 0x51, 0x19, 0xFE, 0xC4, +0x54, 0x03, 0x90, 0xA1, 0x11, 0xF0, 0x74, 0x91, 0x2A, 0xB1, 0x53, 0xE5, 0x60, 0xF0, 0x74, 0x91, +0x2A, 0x12, 0xAC, 0x54, 0xE5, 0x60, 0xD3, 0x9F, 0x40, 0x04, 0x8F, 0x60, 0x8F, 0x5E, 0xEB, 0x70, +0x02, 0xC1, 0x81, 0xAF, 0x03, 0x8F, 0x61, 0xE5, 0x5E, 0x30, 0xE7, 0x05, 0x85, 0x60, 0x5E, 0x15, +0x61, 0xE5, 0x61, 0x70, 0x02, 0xC1, 0x81, 0xE5, 0x60, 0x64, 0x2C, 0x70, 0x20, 0xE5, 0x5F, 0xD3, +0x94, 0x00, 0x40, 0x19, 0xE5, 0x5F, 0xD3, 0x94, 0x02, 0x50, 0x12, 0x15, 0x5F, 0xD1, 0x8D, 0xFF, +0x75, 0xF0, 0x04, 0xEA, 0x12, 0x51, 0x19, 0x54, 0xF3, 0x4F, 0xF0, 0x15, 0x61, 0xE5, 0x61, 0x60, +0x70, 0x90, 0xA1, 0x13, 0xE0, 0xFF, 0xE5, 0x60, 0xD3, 0x9F, 0x40, 0x5F, 0xE4, 0x90, 0xA1, 0x12, +0xF0, 0x85, 0x60, 0x5E, 0xAD, 0x5E, 0xE5, 0x60, 0x14, 0xFC, 0x90, 0xA1, 0x13, 0xE0, 0xFF, 0xEC, +0xC3, 0x9F, 0x40, 0x41, 0xEC, 0x12, 0xAC, 0x97, 0xEA, 0x12, 0x55, 0x2D, 0xE0, 0xF5, 0x82, 0x75, +0x83, 0x00, 0xEC, 0x54, 0x07, 0x91, 0xC6, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0x12, 0xAC, 0x8D, 0x60, 0x1C, 0xE5, 0x60, 0xAD, 0x04, 0xB4, 0x14, 0x02, 0x7D, 0x0C, 0x90, +0xA1, 0x12, 0xE0, 0x04, 0xF0, 0xE0, 0x65, 0x61, 0x60, 0x0B, 0xA3, 0xE0, 0xFF, 0xED, 0xD3, 0x9F, +0x40, 0x03, 0x1C, 0x80, 0xB5, 0xAF, 0x05, 0x8F, 0x5E, 0x80, 0x06, 0x90, 0xA1, 0x13, 0xE0, 0xF5, +0x5E, 0xAF, 0x02, 0x85, 0x5F, 0x6A, 0xE4, 0xFB, 0xAD, 0x5E, 0x02, 0x77, 0x89, 0xE5, 0x5F, 0x54, +0x03, 0x25, 0xE0, 0x25, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x2E, +0xEF, 0xF0, 0xD1, 0xE8, 0x30, 0xE6, 0x3C, 0x7F, 0x8D, 0x12, 0x47, 0xAF, 0xEF, 0x64, 0x01, 0x70, +0x32, 0x90, 0xA2, 0x2F, 0xF0, 0x90, 0xA2, 0x2F, 0xE0, 0xFD, 0x90, 0xA2, 0x2E, 0xE0, 0x75, 0xF0, +0x10, 0x71, 0x91, 0xE5, 0x82, 0x2D, 0x12, 0x55, 0x36, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x50, 0xE6, +0x90, 0xA2, 0x2F, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x10, 0x40, 0xD9, 0xD1, 0xE8, 0x30, 0xE0, +0x02, 0xF1, 0x58, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x8F, 0x12, 0x47, 0xAF, 0xEF, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x9E, 0xF0, 0xE0, 0xFF, 0x90, 0x9E, 0xEF, 0xE0, 0xB5, +0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x39, 0x90, 0x9E, 0xEF, 0xE0, 0xFE, +0xF1, 0x49, 0xE0, 0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0xA0, 0xF9, 0x74, 0x9E, 0x35, 0xF0, +0xFA, 0x7B, 0x01, 0xAF, 0x05, 0x12, 0x51, 0xFD, 0x90, 0x9E, 0xEF, 0x12, 0x6F, 0xD8, 0xB4, 0x0A, +0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x9E, 0xEF, 0xF0, 0x71, 0xB2, 0x90, 0x9E, 0x92, +0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0xF0, 0x08, 0x90, 0x9E, 0x9F, 0x02, +0x45, 0xA9, 0x41, 0xDC, 0xE4, 0xFF, 0x21, 0x54, 0xE4, 0xFD, 0x7F, 0x8D, 0x02, 0x46, 0xA0, 0x11, +0xE2, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x11, 0xE2, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xF1, 0xC2, 0x12, +0x6A, 0x87, 0xFF, 0xF5, 0x55, 0x12, 0x06, 0x89, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, 0x56, +0xDE, 0xF5, 0x56, 0x80, 0x02, 0x8F, 0x56, 0x85, 0x55, 0x54, 0xE5, 0x54, 0xD3, 0x95, 0x56, 0x50, +0x22, 0x12, 0x57, 0xE3, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFD, 0xAF, 0x54, 0x12, 0x61, 0xD3, 0xAF, +0x54, 0x12, 0x5F, 0x2F, 0xEF, 0xAF, 0x54, 0x70, 0x04, 0xF1, 0x66, 0x80, 0x02, 0xF1, 0x5F, 0x05, +0x54, 0x80, 0xD7, 0xE5, 0x55, 0x70, 0x0A, 0xFF, 0x12, 0x5F, 0x2F, 0xEF, 0x70, 0x03, 0x12, 0xAB, +0x6D, 0x22, 0x8B, 0x51, 0x8A, 0x52, 0x89, 0x53, 0x22, 0x71, 0xB2, 0x7F, 0x02, 0x02, 0x6F, 0x57, +0x12, 0x45, 0x39, 0x78, 0x01, 0x02, 0x08, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x98, 0xF5, 0x83, 0x22, +0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, +0xE0, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x7F, 0x12, 0x80, 0x08, 0xD0, 0x07, 0xD0, 0x05, 0xD0, +0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xFF, 0xA3, 0xF0, 0xED, 0x04, 0x90, 0x01, 0xC4, +0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, +0xC0, 0x05, 0xC0, 0x07, 0x7D, 0x15, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x80, 0x11, 0x08, 0xD0, +0x07, 0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0xF0, +0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, +0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0x3C, 0xF0, 0x74, +0x80, 0xA3, 0xF0, 0x11, 0xAE, 0xE5, 0x14, 0x30, 0xE7, 0x02, 0x11, 0x92, 0x74, 0x3C, 0x04, 0x90, +0x01, 0xC4, 0xF0, 0x74, 0x80, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, +0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, +0xE0, 0x32, 0x7F, 0x01, 0x7E, 0x00, 0x12, 0x3D, 0xC2, 0x7F, 0xF2, 0x12, 0x47, 0xAF, 0xEF, 0x20, +0xE6, 0x0B, 0x7F, 0x05, 0x12, 0x47, 0xF7, 0xFD, 0x7F, 0x05, 0x12, 0x46, 0xA0, 0x22, 0x7F, 0x54, +0x12, 0x47, 0xAF, 0xE5, 0x0D, 0x5F, 0xF5, 0x11, 0x7F, 0x55, 0x12, 0x47, 0xAF, 0xE5, 0x0E, 0x5F, +0xF5, 0x12, 0x7F, 0x56, 0x12, 0x47, 0xAF, 0xE5, 0x0F, 0x5F, 0xF5, 0x13, 0x7F, 0x57, 0x12, 0x47, +0xAF, 0xE5, 0x10, 0x5F, 0xF5, 0x14, 0xAD, 0x11, 0x7F, 0x54, 0x12, 0x46, 0xA0, 0xAD, 0x12, 0x7F, +0x55, 0x12, 0x46, 0xA0, 0xAD, 0x13, 0x7F, 0x56, 0x12, 0x46, 0xA0, 0xAD, 0x14, 0x7F, 0x57, 0x12, +0x46, 0xA0, 0x53, 0x91, 0xEF, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, +0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, +0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xF6, 0xF0, 0x74, 0x80, 0xA3, 0xF0, 0x12, 0xA2, 0x35, +0xE5, 0x19, 0x30, 0xE1, 0x02, 0x31, 0xB1, 0xE5, 0x19, 0x30, 0xE4, 0x03, 0x12, 0x7F, 0xC9, 0xE5, +0x19, 0x30, 0xE5, 0x03, 0x12, 0xA2, 0x92, 0xE5, 0x19, 0x30, 0xE6, 0x03, 0x12, 0xA2, 0xCE, 0xE5, +0x1B, 0x30, 0xE0, 0x02, 0x51, 0x49, 0xE5, 0x1B, 0x30, 0xE1, 0x03, 0x12, 0x95, 0x5F, 0xE5, 0x1B, +0x30, 0xE2, 0x03, 0x12, 0xA2, 0xDB, 0xE5, 0x1B, 0x30, 0xE3, 0x02, 0x51, 0x33, 0xE5, 0x1B, 0x30, +0xE4, 0x02, 0x51, 0xA6, 0xE5, 0x1B, 0x30, 0xE5, 0x03, 0x12, 0xA4, 0x0D, 0xE5, 0x1B, 0x30, 0xE6, +0x03, 0x12, 0x68, 0x56, 0xE5, 0x1C, 0x30, 0xE1, 0x02, 0x51, 0xD0, 0xE5, 0x1C, 0x30, 0xE4, 0x03, +0x12, 0x7F, 0x54, 0xE5, 0x1C, 0x30, 0xE5, 0x03, 0x12, 0x7F, 0x52, 0x74, 0xF6, 0x04, 0x90, 0x01, +0xC4, 0xF0, 0x74, 0x80, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, +0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, +0x32, 0xE4, 0xFF, 0x90, 0xA1, 0x1B, 0xEF, 0xF0, 0x90, 0x04, 0x7E, 0xE0, 0xF5, 0x64, 0xA3, 0xE0, +0xF5, 0x65, 0x65, 0x64, 0x60, 0x6C, 0x90, 0xA1, 0x1C, 0x74, 0x03, 0xF0, 0x90, 0xA1, 0x2A, 0x74, +0x08, 0xF0, 0xE5, 0x65, 0x04, 0x54, 0x0F, 0xF5, 0x66, 0xE4, 0xF5, 0x63, 0xE5, 0x66, 0x75, 0xF0, +0x08, 0xA4, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE5, 0x82, 0x25, 0x63, 0x12, +0x55, 0x36, 0xE0, 0xFF, 0x74, 0x1E, 0x25, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0xA1, 0xF5, 0x83, 0xEF, +0xF0, 0x05, 0x63, 0xE5, 0x63, 0xB4, 0x08, 0xD4, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x1C, 0x12, 0x6E, +0xA2, 0xE5, 0x65, 0x04, 0x54, 0x0F, 0xF5, 0x65, 0xB4, 0x0F, 0x03, 0xE4, 0xF5, 0x65, 0x90, 0x04, +0x7F, 0xE5, 0x65, 0xF0, 0x90, 0xA1, 0x1B, 0xE0, 0x7F, 0x04, 0x70, 0x03, 0x02, 0x6F, 0x57, 0x12, +0x98, 0x0D, 0x22, 0x12, 0x5F, 0x8C, 0x64, 0x01, 0x70, 0x0E, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x08, +0x51, 0xC4, 0x12, 0x6F, 0xBE, 0x12, 0x48, 0x2C, 0x22, 0x90, 0x9F, 0x9E, 0xE0, 0x30, 0xE0, 0x10, +0xA3, 0x74, 0x01, 0xF0, 0x90, 0x9F, 0x9E, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, 0x02, 0x51, 0xFC, +0x71, 0x8D, 0x90, 0xA0, 0x5F, 0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xFF, 0x12, 0x65, 0x1D, 0x22, 0x71, +0x20, 0x12, 0x5C, 0xCD, 0x51, 0x62, 0x90, 0xA0, 0x52, 0xE0, 0x30, 0xE0, 0x28, 0x12, 0x97, 0x85, +0x90, 0xA0, 0x55, 0xE0, 0x60, 0x05, 0x14, 0xF0, 0x02, 0x5E, 0xF0, 0x90, 0xA0, 0x53, 0xE0, 0x14, +0x90, 0xA0, 0x55, 0xF0, 0x90, 0x05, 0x73, 0x74, 0x01, 0xF0, 0xE4, 0xFF, 0x12, 0x88, 0xD8, 0x12, +0x5C, 0xCD, 0x12, 0x8F, 0xC2, 0x22, 0x12, 0x5F, 0x8C, 0x64, 0x01, 0x70, 0x16, 0x90, 0x9F, 0xA7, +0xE0, 0x60, 0x10, 0x51, 0xC4, 0x90, 0x9F, 0xA3, 0xE0, 0x12, 0x8F, 0x7F, 0x54, 0x07, 0x70, 0x03, +0x12, 0x68, 0x44, 0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x22, +0x90, 0x9F, 0xA7, 0xE0, 0x70, 0x07, 0x90, 0x9F, 0x9E, 0xE0, 0x30, 0xE0, 0x12, 0x90, 0x9F, 0x9E, +0xE0, 0x30, 0xE0, 0x08, 0x51, 0xF0, 0xBF, 0x01, 0x06, 0x02, 0xA3, 0x1C, 0x12, 0x5E, 0x6F, 0x22, +0x90, 0x05, 0x43, 0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x9F, 0x9D, 0xE0, 0xB4, 0x01, 0x04, 0x7F, 0x04, 0x80, 0x0B, 0x51, 0xF0, +0xBF, 0x01, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x91, 0x59, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0xE4, 0x90, 0xA1, 0x2B, 0xF0, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x61, 0x12, 0x5F, 0x8C, 0x64, 0x01, +0x70, 0x5A, 0xF1, 0xD6, 0xF1, 0xC3, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x12, +0xAC, 0x49, 0xF0, 0x12, 0x67, 0x80, 0xE4, 0x90, 0x9F, 0xAE, 0xF0, 0x90, 0x9F, 0x9E, 0xE0, 0x30, +0xE0, 0x15, 0x90, 0x9F, 0xA2, 0xE0, 0xB4, 0x02, 0x05, 0xE4, 0x90, 0xA1, 0x2B, 0xF0, 0x51, 0xF0, +0xEF, 0x70, 0x04, 0x90, 0xA1, 0x2B, 0xF0, 0x90, 0xA1, 0x2B, 0xE0, 0x60, 0x1F, 0x90, 0x9F, 0xAB, +0xE0, 0x44, 0x10, 0x12, 0xA9, 0x18, 0x90, 0x9F, 0xAF, 0xE0, 0x90, 0xA1, 0xDA, 0x12, 0x48, 0x2C, +0x90, 0x9F, 0xAA, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x5A, 0x9D, 0x91, 0x33, 0x22, 0xE4, 0xF5, 0x63, +0x90, 0x9F, 0xA7, 0xE0, 0x70, 0x02, 0x81, 0x28, 0x12, 0x5F, 0x8C, 0x64, 0x01, 0x60, 0x02, 0x81, +0x28, 0xF1, 0xC4, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x12, 0xAC, 0x49, 0xD1, +0xF5, 0x60, 0x22, 0x24, 0xFE, 0x60, 0x03, 0x04, 0x70, 0x1E, 0x90, 0x9F, 0xAE, 0xE0, 0x14, 0xF0, +0xE0, 0xFF, 0x60, 0x06, 0x90, 0x9F, 0xB0, 0xE0, 0x60, 0x0E, 0xEF, 0x70, 0x08, 0x90, 0x9F, 0xAD, +0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x75, 0x63, 0x01, 0x90, 0x9F, 0x9E, 0xE0, 0x30, 0xE0, 0x11, 0x90, +0x9F, 0xA2, 0xE0, 0xB4, 0x02, 0x03, 0xE4, 0xF5, 0x63, 0x51, 0xF0, 0xEF, 0x70, 0x02, 0xF5, 0x63, +0xE5, 0x63, 0x60, 0x34, 0x90, 0x9F, 0xAB, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x9F, 0xB0, 0xE0, 0x60, +0x03, 0xB4, 0x01, 0x04, 0x91, 0x29, 0x80, 0x08, 0x91, 0x29, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, +0xFF, 0x90, 0x9F, 0xAF, 0xE0, 0x2F, 0x90, 0xA1, 0xDA, 0x12, 0x48, 0x2C, 0x90, 0x9F, 0xAA, 0xE0, +0x20, 0xE2, 0x03, 0x12, 0x5A, 0x9D, 0x91, 0x33, 0x22, 0xE4, 0x90, 0xA1, 0xD9, 0xF0, 0x90, 0x9F, +0xB0, 0xE0, 0x22, 0x12, 0x9D, 0x3F, 0x30, 0xE0, 0x1F, 0xD1, 0xD3, 0x20, 0xE0, 0x1A, 0xB1, 0xA8, +0x30, 0xE0, 0x04, 0x7F, 0x03, 0x80, 0x0E, 0x12, 0x9D, 0x48, 0x54, 0x3F, 0x30, 0xE0, 0x04, 0x7F, +0x0D, 0x80, 0x02, 0x7F, 0x09, 0x12, 0x62, 0xC3, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x9F, 0xA1, 0xE0, 0x90, 0xA2, 0x37, 0xF0, 0x6F, 0x70, 0x02, 0xA1, 0x67, 0xEF, 0x14, 0x60, +0x42, 0x14, 0x60, 0x70, 0x14, 0x70, 0x02, 0xA1, 0x12, 0x14, 0x70, 0x02, 0xA1, 0x3E, 0x24, 0x04, +0x60, 0x02, 0xA1, 0x67, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x04, 0x04, 0xB1, 0x86, 0xA1, 0x67, 0x90, +0xA2, 0x37, 0xE0, 0xB4, 0x02, 0x04, 0xB1, 0x92, 0xA1, 0x67, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x03, +0x04, 0xB1, 0x9C, 0xA1, 0x67, 0x90, 0xA2, 0x37, 0xE0, 0x64, 0x01, 0x60, 0x02, 0xA1, 0x67, 0xB1, +0x89, 0xA1, 0x67, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0x5F, 0xD0, 0xA1, 0x67, 0x90, +0xA2, 0x37, 0xE0, 0xB4, 0x02, 0x05, 0x12, 0x5F, 0xDE, 0xA1, 0x67, 0x90, 0xA2, 0x37, 0xE0, 0xB4, +0x03, 0x05, 0x12, 0x5F, 0xC7, 0xA1, 0x67, 0x90, 0xA2, 0x37, 0xE0, 0x60, 0x02, 0xA1, 0x67, 0x12, +0x5F, 0xEC, 0xA1, 0x67, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0xA8, 0xB8, 0x80, 0x77, +0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x01, 0x05, 0x12, 0x67, 0xDF, 0x80, 0x6B, 0x90, 0xA2, 0x37, 0xE0, +0xB4, 0x03, 0x05, 0x12, 0x67, 0xEA, 0x80, 0x5F, 0x90, 0xA2, 0x37, 0xE0, 0x70, 0x59, 0xF1, 0xD0, +0x80, 0x55, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0xA8, 0xAB, 0x80, 0x49, 0x90, 0xA2, +0x37, 0xE0, 0xB4, 0x01, 0x04, 0xB1, 0x78, 0x80, 0x3E, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x02, 0x04, +0xB1, 0x97, 0x80, 0x33, 0x90, 0xA2, 0x37, 0xE0, 0x70, 0x2D, 0xB1, 0x75, 0x80, 0x29, 0x90, 0xA2, +0x37, 0xE0, 0xB4, 0x03, 0x04, 0xB1, 0xA1, 0x80, 0x1E, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x01, 0x04, +0xB1, 0x6F, 0x80, 0x13, 0x90, 0xA2, 0x37, 0xE0, 0xB4, 0x02, 0x04, 0xD1, 0xDA, 0x80, 0x08, 0x90, +0xA2, 0x37, 0xE0, 0x70, 0x02, 0xB1, 0x6C, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x5F, 0xEC, 0x7D, +0x1F, 0xD1, 0xE3, 0xF0, 0x22, 0x12, 0x5F, 0xEC, 0x7D, 0x21, 0x7F, 0xFF, 0x12, 0x49, 0x22, 0x90, +0x9F, 0xA1, 0x74, 0x03, 0xF0, 0x22, 0x12, 0x5F, 0xD0, 0x12, 0xA9, 0xB9, 0xE4, 0x90, 0x9F, 0xA1, +0xF0, 0x22, 0x12, 0x5F, 0xDE, 0x80, 0xF2, 0x12, 0x64, 0xAA, 0x80, 0xE3, 0x12, 0x5F, 0xC7, 0x80, +0xE8, 0x7D, 0x25, 0xD1, 0xE3, 0xF0, 0x22, 0xF0, 0x90, 0xA0, 0x62, 0xE0, 0xC4, 0x54, 0x0F, 0x22, +0x90, 0xA1, 0x2B, 0xEF, 0xF0, 0x7F, 0x03, 0x12, 0x66, 0xEC, 0xB1, 0xA8, 0x90, 0xA0, 0x72, 0x30, +0xE0, 0x05, 0x74, 0x05, 0xF0, 0x80, 0x03, 0xE0, 0x04, 0xF0, 0x90, 0xA0, 0x63, 0x12, 0x8F, 0xB4, +0x20, 0xE0, 0x05, 0xD1, 0xD3, 0x30, 0xE0, 0x37, 0xB1, 0xA8, 0x30, 0xE0, 0x0A, 0x90, 0xA0, 0x60, +0xE0, 0xFF, 0x90, 0xA0, 0x70, 0x80, 0x21, 0x90, 0xA1, 0x2B, 0xE0, 0xFC, 0xB4, 0x01, 0x0D, 0x90, +0xA0, 0x60, 0xE0, 0xFE, 0x90, 0xA0, 0x6F, 0xE0, 0xC3, 0x9E, 0x80, 0x0F, 0xEC, 0xB4, 0x04, 0x0F, +0x90, 0xA0, 0x61, 0xE0, 0xFF, 0x90, 0xA0, 0x6F, 0xE0, 0xC3, 0x9F, 0x90, 0xA0, 0x76, 0xF0, 0x12, +0x9B, 0xC4, 0x30, 0xE0, 0x21, 0x12, 0x9B, 0xBB, 0x20, 0xE0, 0x02, 0xC1, 0x9E, 0xD1, 0xCA, 0x50, +0x0A, 0xEF, 0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xE4, 0xFD, 0x80, 0x05, 0x7B, 0x7F, 0x7D, 0xFF, 0xE4, +0xFF, 0x12, 0x4E, 0xDD, 0x80, 0x68, 0x12, 0x9B, 0xB3, 0x30, 0xE0, 0x49, 0x12, 0xAC, 0xCE, 0xFD, +0x7F, 0x04, 0x12, 0x5A, 0xA1, 0x12, 0x4F, 0xD0, 0x30, 0xE0, 0x3A, 0x90, 0xA0, 0x66, 0xE0, 0x44, +0x02, 0xF0, 0x54, 0xFB, 0xF0, 0xE4, 0x90, 0xA0, 0x75, 0xF0, 0x90, 0xA0, 0x72, 0xF0, 0x90, 0xA1, +0x2B, 0xE0, 0xFF, 0xB4, 0x01, 0x08, 0x90, 0xA0, 0x67, 0x74, 0x06, 0xF0, 0x80, 0x0A, 0xEF, 0xB4, +0x04, 0x06, 0x90, 0xA0, 0x67, 0x74, 0x07, 0xF0, 0x90, 0xA0, 0x51, 0xE0, 0x60, 0x07, 0x90, 0xA0, +0x66, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xA1, 0x2B, 0xE0, 0xB4, 0x01, 0x04, 0x7D, 0x06, 0x80, 0x09, +0x90, 0xA1, 0x2B, 0xE0, 0xB4, 0x04, 0x07, 0x7D, 0x0C, 0x7F, 0x6F, 0x12, 0x49, 0x22, 0x90, 0xA0, +0x63, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x15, 0xD1, 0xCA, 0x50, 0x0A, 0xEF, 0x7F, +0x00, 0x25, 0xE0, 0x25, 0xE0, 0xFE, 0x80, 0x04, 0x7F, 0xFF, 0x7E, 0x7F, 0x12, 0x4E, 0x12, 0x90, +0xA0, 0x62, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0x5C, 0x93, 0x22, 0x90, 0xA0, 0x76, 0xE0, 0xFF, 0xC3, +0x94, 0x20, 0x22, 0xEF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22, 0x12, 0x64, 0xAA, 0x7D, 0x24, 0xD1, +0xE3, 0xF0, 0x22, 0x7F, 0x6F, 0x12, 0x49, 0x22, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0, 0x90, +0x9F, 0xA1, 0x74, 0x04, 0x22, 0xF0, 0x90, 0x9F, 0xA5, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x22, 0xF1, +0xC4, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0xA1, 0x1B, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0x12, 0x5F, 0x8C, 0x64, 0x01, 0x60, 0x02, 0xE1, 0xB6, 0x90, 0x9F, 0xA7, 0xE0, +0x70, 0x02, 0xE1, 0xB6, 0xD1, 0xF6, 0x64, 0x01, 0x70, 0x22, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x9F, +0xAE, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, 0x9F, 0xAD, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90, +0x9F, 0xAD, 0xE0, 0xFE, 0xFF, 0x80, 0x00, 0x90, 0x9F, 0xAE, 0xEF, 0xF0, 0x12, 0x8B, 0x78, 0x12, +0xAB, 0xFA, 0xE4, 0x90, 0x9F, 0xB0, 0x12, 0xAC, 0x3E, 0x51, 0xC4, 0x12, 0x8F, 0x82, 0x54, 0xEF, +0xD1, 0xF5, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x0F, 0x90, 0x9F, 0x9E, 0xE0, 0x30, 0xE0, 0x05, 0x12, +0x68, 0xC1, 0x80, 0x03, 0x12, 0x68, 0x75, 0x90, 0x9F, 0xA4, 0xE0, 0x12, 0x5E, 0xCD, 0x30, 0xE0, +0x35, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x2C, 0x90, 0x9F, 0xAD, 0xE0, 0xFF, 0xA3, +0xE0, 0x6F, 0x70, 0x22, 0x90, 0x9F, 0xA4, 0xE0, 0x44, 0x40, 0xF0, 0xF1, 0xD6, 0xF0, 0x90, 0x01, +0x3F, 0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, 0x12, 0x88, 0xD0, 0x12, 0x5F, 0xA7, 0x12, 0x8F, 0xBB, +0x90, 0x9F, 0xAE, 0xE0, 0x14, 0xF0, 0x90, 0x9F, 0x9E, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x03, 0x12, +0xAB, 0xFA, 0x22, 0xF0, 0x90, 0x05, 0x62, 0xE0, 0xFE, 0x90, 0x05, 0x61, 0xE0, 0xFD, 0xED, 0x22, +0x12, 0x5F, 0xEC, 0x02, 0x67, 0xDF, 0x90, 0x9F, 0xAD, 0xE0, 0x90, 0x05, 0x73, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, -0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0x4E, -0xF0, 0x74, 0x78, 0xA3, 0xF0, 0x11, 0xC0, 0xE5, 0x14, 0x30, 0xE7, 0x02, 0x11, 0xA4, 0x74, 0x4E, -0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x78, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, -0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, -0xF0, 0xD0, 0xE0, 0x32, 0x7F, 0x01, 0x7E, 0x00, 0x12, 0x3D, 0xC2, 0x7F, 0xF2, 0x12, 0x47, 0xBF, -0xEF, 0x20, 0xE6, 0x0B, 0x7F, 0x05, 0x12, 0x47, 0xFA, 0xFD, 0x7F, 0x05, 0x12, 0x46, 0xA0, 0x22, -0x7F, 0x54, 0x12, 0x47, 0xBF, 0xE5, 0x0D, 0x5F, 0xF5, 0x11, 0x7F, 0x55, 0x12, 0x47, 0xBF, 0xE5, -0x0E, 0x5F, 0xF5, 0x12, 0x7F, 0x56, 0x12, 0x47, 0xBF, 0xE5, 0x0F, 0x5F, 0xF5, 0x13, 0x7F, 0x57, -0x12, 0x47, 0xBF, 0xE5, 0x10, 0x5F, 0xF5, 0x14, 0xAD, 0x11, 0x7F, 0x54, 0x12, 0x46, 0xA0, 0xAD, -0x12, 0x7F, 0x55, 0x12, 0x46, 0xA0, 0xAD, 0x13, 0x7F, 0x56, 0x12, 0x46, 0xA0, 0xAD, 0x14, 0x7F, -0x57, 0x12, 0x46, 0xA0, 0x53, 0x91, 0xEF, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, -0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, -0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0x08, 0xF0, 0x74, 0x79, 0xA3, 0xF0, 0x12, -0xA0, 0x4C, 0xE5, 0x19, 0x30, 0xE1, 0x02, 0xD1, 0x56, 0xE5, 0x19, 0x30, 0xE4, 0x02, 0xD1, 0x40, -0xE5, 0x19, 0x30, 0xE5, 0x03, 0x12, 0xA0, 0xA9, 0xE5, 0x19, 0x30, 0xE6, 0x03, 0x12, 0xA0, 0xE5, -0xE5, 0x1B, 0x30, 0xE0, 0x03, 0x12, 0x87, 0x43, 0xE5, 0x1B, 0x30, 0xE1, 0x03, 0x12, 0x96, 0x00, -0xE5, 0x1B, 0x30, 0xE2, 0x03, 0x12, 0x92, 0x54, 0xE5, 0x1B, 0x30, 0xE3, 0x03, 0x12, 0x91, 0xBE, -0xE5, 0x1B, 0x30, 0xE4, 0x03, 0x12, 0x91, 0xDC, 0xE5, 0x1B, 0x30, 0xE5, 0x03, 0x12, 0x97, 0x95, -0xE5, 0x1B, 0x30, 0xE6, 0x03, 0x12, 0x97, 0x7E, 0xE5, 0x1C, 0x30, 0xE1, 0x03, 0x12, 0xA0, 0xF2, -0xE5, 0x1C, 0x30, 0xE4, 0x02, 0xD1, 0xD8, 0xE5, 0x1C, 0x30, 0xE5, 0x02, 0x31, 0xC4, 0x74, 0x08, -0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x79, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, -0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, -0xF0, 0xD0, 0xE0, 0x32, 0xE4, 0xF5, 0x63, 0x74, 0x8D, 0x25, 0x63, 0x12, 0x95, 0xF8, 0xE0, 0x70, -0x02, 0x41, 0x53, 0xE5, 0x63, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0xE5, 0x63, 0x54, 0x07, 0xFE, -0x74, 0x81, 0x2F, 0x12, 0x77, 0x6C, 0xE0, 0xFD, 0xAF, 0x06, 0xB1, 0x23, 0x80, 0x05, 0xC3, 0x33, -0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x60, 0x59, 0x75, 0xF0, 0x10, 0xE5, 0x63, 0x12, -0x75, 0xD7, 0xE0, 0x20, 0xE7, 0x02, 0x80, 0x10, 0x75, 0xF0, 0x10, 0xE5, 0x63, 0x90, 0x81, 0x02, -0x12, 0x45, 0xA9, 0xE0, 0xFF, 0x20, 0xE7, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x20, 0xF0, 0x80, -0x32, 0xEF, 0x30, 0xE6, 0x0A, 0x51, 0x6B, 0x54, 0x03, 0xF5, 0x6A, 0xE4, 0xFB, 0x80, 0x1F, 0x51, -0x5F, 0xE0, 0x04, 0xF0, 0x51, 0x5F, 0xE0, 0xD3, 0x94, 0x03, 0x40, 0x0A, 0xAF, 0x63, 0x51, 0x85, -0x51, 0x5F, 0xE4, 0xF0, 0x80, 0x0D, 0x51, 0x6B, 0x54, 0x03, 0xF5, 0x6A, 0x7B, 0x01, 0xAF, 0x63, -0x12, 0x75, 0xDD, 0x05, 0x63, 0xE5, 0x63, 0xC3, 0x94, 0x80, 0x50, 0x02, 0x21, 0xC7, 0x22, 0x74, -0x92, 0x25, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x9C, 0xF5, 0x83, 0x22, 0x75, 0xF0, 0x10, 0xE5, 0x63, -0x90, 0x81, 0x00, 0x12, 0x45, 0xA9, 0xE0, 0xFD, 0x75, 0xF0, 0x10, 0xE5, 0x63, 0x90, 0x81, 0x05, -0x12, 0x45, 0xA9, 0xE0, 0x22, 0x75, 0xF0, 0x10, 0xEF, 0x51, 0x7D, 0x54, 0x03, 0xFE, 0x12, 0x77, -0x90, 0xE0, 0xFC, 0x51, 0xD9, 0xE0, 0x54, 0x7F, 0xFD, 0x64, 0x2C, 0x70, 0x27, 0x75, 0xF0, 0x04, -0xEF, 0x12, 0x51, 0x07, 0xF9, 0x54, 0x03, 0xFB, 0xEE, 0xD3, 0x9B, 0x50, 0x17, 0xEE, 0x60, 0x14, -0x1E, 0xEE, 0xB1, 0x19, 0xFB, 0x75, 0xF0, 0x04, 0xEF, 0x90, 0x96, 0x15, 0x12, 0x45, 0xA9, 0xE9, -0x54, 0xF3, 0x4B, 0xF0, 0xED, 0xD3, 0x9C, 0x40, 0x02, 0xAD, 0x04, 0x51, 0xD9, 0xE0, 0x54, 0x80, -0x42, 0x05, 0x8E, 0x6A, 0xE4, 0xFB, 0x02, 0x75, 0xDD, 0x74, 0x12, 0x2F, 0xF5, 0x82, 0xE4, 0x34, -0x9D, 0xF5, 0x83, 0x22, 0xAB, 0x07, 0x75, 0xF0, 0x10, 0xEB, 0xF1, 0xBC, 0xF5, 0x5E, 0xE4, 0xF5, -0x62, 0xE5, 0x5E, 0x54, 0x7F, 0xF9, 0xE5, 0x5E, 0x54, 0x80, 0xFA, 0x75, 0xF0, 0x04, 0xEB, 0x12, -0x77, 0x94, 0xE0, 0xF5, 0x60, 0x75, 0xF0, 0x04, 0xEB, 0x12, 0x51, 0x07, 0xFF, 0xC4, 0x54, 0x03, -0xF5, 0x61, 0x12, 0x77, 0x3E, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x5E, 0x4A, 0xFF, -0x74, 0x12, 0x2B, 0x51, 0xDC, 0xEF, 0xF0, 0x75, 0xF0, 0x10, 0xEB, 0x51, 0x7D, 0x54, 0x03, 0xF5, -0x5F, 0x74, 0x12, 0x2B, 0x12, 0xA9, 0xB3, 0xE9, 0x64, 0x2C, 0x70, 0x29, 0x75, 0xF0, 0x04, 0xEB, -0x12, 0x51, 0x07, 0xFF, 0x54, 0x03, 0xFE, 0xE5, 0x5F, 0xC3, 0x9E, 0x50, 0x18, 0x05, 0x5F, 0xB1, -0x17, 0xFE, 0x75, 0xF0, 0x04, 0xEB, 0x90, 0x96, 0x15, 0x12, 0x45, 0xA9, 0xEF, 0x54, 0xF3, 0x4E, -0xF0, 0x89, 0x5E, 0x80, 0x7E, 0xE9, 0xC3, 0x95, 0x60, 0x50, 0x43, 0xE9, 0x04, 0xFD, 0xED, 0xD3, -0x95, 0x60, 0x50, 0x6F, 0xED, 0x12, 0xA9, 0xE6, 0xEB, 0x12, 0x56, 0x05, 0xE0, 0xF5, 0x82, 0x75, -0x83, 0x00, 0xED, 0xB1, 0x20, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xF1, 0xDD, -0x60, 0x19, 0xB9, 0x13, 0x10, 0x79, 0x18, 0x89, 0x5E, 0x74, 0x12, 0x2B, 0x12, 0x56, 0x2B, 0xE0, -0x44, 0x04, 0xF0, 0x80, 0x3E, 0xA9, 0x05, 0x89, 0x5E, 0x80, 0x38, 0x0D, 0x80, 0xC0, 0xE9, 0x65, -0x60, 0x70, 0x26, 0x75, 0xF0, 0x04, 0xEB, 0x12, 0x54, 0x0F, 0xFF, 0xC4, 0x13, 0x54, 0x07, 0x30, -0xE0, 0x0C, 0xE5, 0x5E, 0x20, 0xE7, 0x07, 0xE9, 0x44, 0x80, 0xF5, 0x5E, 0x80, 0x15, 0x12, 0x77, -0x3E, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x74, 0x12, 0x2B, 0x51, 0xDC, 0xE5, 0x60, -0xF0, 0xF5, 0x5E, 0xAF, 0x03, 0x85, 0x5F, 0x6A, 0x7B, 0x01, 0xAD, 0x5E, 0x02, 0x75, 0xDD, 0xAA, -0x07, 0xAB, 0x05, 0x75, 0xF0, 0x10, 0xEA, 0xF1, 0xBC, 0xF5, 0x5E, 0x54, 0x7F, 0xF5, 0x60, 0x75, -0xF0, 0x04, 0xEA, 0x12, 0x56, 0xC6, 0xE0, 0x90, 0xA1, 0x00, 0xF0, 0x75, 0xF0, 0x04, 0xEA, 0x12, -0x77, 0x94, 0xE0, 0xFF, 0x75, 0xF0, 0x10, 0xEA, 0x51, 0x7D, 0x54, 0x03, 0xF5, 0x5F, 0xE5, 0x60, -0x12, 0x77, 0xB1, 0xE4, 0x93, 0xFC, 0x74, 0x01, 0x93, 0xFD, 0xEA, 0x12, 0x77, 0x50, 0xF5, 0x83, -0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x75, 0xF0, 0x04, 0xEA, 0x12, 0x51, 0x07, 0xFE, 0xC4, 0x54, 0x03, -0x90, 0xA0, 0xFE, 0xF0, 0x74, 0x12, 0x2A, 0x51, 0xDC, 0xE5, 0x60, 0xF0, 0x74, 0x12, 0x2A, 0x12, -0xA9, 0xB3, 0xE5, 0x60, 0xD3, 0x9F, 0x40, 0x04, 0x8F, 0x60, 0x8F, 0x5E, 0xEB, 0x70, 0x02, 0xA1, -0x0B, 0xAF, 0x03, 0x8F, 0x61, 0xE5, 0x5E, 0x30, 0xE7, 0x05, 0x85, 0x60, 0x5E, 0x15, 0x61, 0xE5, -0x61, 0x70, 0x02, 0xA1, 0x0B, 0xE5, 0x60, 0x64, 0x2C, 0x70, 0x20, 0xE5, 0x5F, 0xD3, 0x94, 0x00, -0x40, 0x19, 0xE5, 0x5F, 0xD3, 0x94, 0x02, 0x50, 0x12, 0x15, 0x5F, 0xB1, 0x17, 0xFF, 0x75, 0xF0, -0x04, 0xEA, 0x12, 0x51, 0x07, 0x54, 0xF3, 0x4F, 0xF0, 0x15, 0x61, 0xE5, 0x61, 0x60, 0x6C, 0x90, -0xA1, 0x00, 0xE0, 0xFF, 0xE5, 0x60, 0xD3, 0x9F, 0x40, 0x5B, 0xE4, 0x90, 0xA0, 0xFF, 0xF0, 0x85, -0x60, 0x5E, 0xAD, 0x5E, 0xE5, 0x60, 0x14, 0xFC, 0x90, 0xA1, 0x00, 0xE0, 0xFF, 0xEC, 0xC3, 0x9F, -0x40, 0x3D, 0xEC, 0x12, 0xA9, 0xE6, 0xEA, 0x12, 0x56, 0x05, 0xE0, 0xF5, 0x82, 0x75, 0x83, 0x00, -0xEC, 0xB1, 0x20, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xF1, 0xDD, 0x60, 0x1C, -0xE5, 0x60, 0xAD, 0x04, 0xB4, 0x14, 0x02, 0x7D, 0x0C, 0x90, 0xA0, 0xFF, 0xE0, 0x04, 0xF0, 0xE0, -0x65, 0x61, 0x60, 0x0B, 0xA3, 0xE0, 0xFF, 0xED, 0xD3, 0x9F, 0x40, 0x03, 0x1C, 0x80, 0xB9, 0xAF, -0x05, 0x8F, 0x5E, 0x80, 0x06, 0x90, 0xA1, 0x00, 0xE0, 0xF5, 0x5E, 0xAF, 0x02, 0x85, 0x5F, 0x6A, -0xE4, 0xFB, 0xAD, 0x5E, 0x02, 0x75, 0xDD, 0xE5, 0x5F, 0x54, 0x03, 0x25, 0xE0, 0x25, 0xE0, 0x22, -0x54, 0x07, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22, 0x90, 0x01, 0xCC, 0xE0, 0x54, -0x0F, 0x90, 0xA1, 0xFE, 0xF0, 0x90, 0xA1, 0xFE, 0xE0, 0xFD, 0x70, 0x02, 0xC1, 0x36, 0x90, 0x9D, -0xF0, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x9D, -0xF1, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01, -0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0xA1, 0xF3, 0xE0, 0xB1, 0x22, 0x80, 0x05, 0xC3, 0x33, -0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0xC1, 0x19, 0xE4, 0x90, 0xA1, 0xFF, -0xF0, 0x90, 0xA1, 0xFF, 0xE0, 0xF9, 0xC3, 0x94, 0x04, 0x50, 0x42, 0xD1, 0x38, 0xA4, 0xFF, 0xE9, -0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xD0, 0xD1, 0x47, 0x12, 0x9D, 0x7A, -0xE5, 0x82, 0x29, 0x12, 0x56, 0x0E, 0xEF, 0xD1, 0x37, 0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, -0x74, 0xF0, 0xD1, 0x47, 0x75, 0xF0, 0x08, 0x90, 0x9D, 0xA4, 0x12, 0x45, 0xA9, 0xE5, 0x82, 0x29, -0x12, 0x56, 0x0E, 0xEF, 0xF0, 0x90, 0xA1, 0xFF, 0xE0, 0x04, 0xF0, 0x80, 0xB4, 0x90, 0xA1, 0xFE, -0xE0, 0xFF, 0x90, 0xA1, 0xF3, 0x12, 0xA9, 0x1B, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, -0x90, 0xA1, 0xFE, 0xF0, 0x90, 0xA1, 0xF3, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, -0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0xA1, 0xF3, 0xE0, 0x04, 0xF0, 0xE0, 0x54, -0x03, 0xF0, 0x90, 0x9D, 0xF1, 0x12, 0x8F, 0x7B, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x70, 0x02, -0xA1, 0x35, 0xE4, 0x90, 0x9D, 0xF1, 0xF0, 0xA1, 0x35, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x02, 0xF0, -0x90, 0xA1, 0xF3, 0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A, 0xD1, 0x37, 0x90, 0x01, 0xD0, 0x12, 0x45, -0xA9, 0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, 0xF0, 0x90, 0xA1, 0xF3, 0xE0, 0x75, 0xF0, 0x04, 0x22, -0xB1, 0x2B, 0x7F, 0x02, 0x02, 0x86, 0x68, 0x2F, 0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, -0xFF, 0x90, 0x9D, 0xF1, 0xE0, 0x22, 0xE4, 0xFF, 0x90, 0xA1, 0x08, 0xEF, 0xF0, 0x90, 0x04, 0x7E, -0xE0, 0xF5, 0x64, 0xA3, 0xE0, 0xF5, 0x65, 0x65, 0x64, 0x60, 0x6C, 0x90, 0xA1, 0x09, 0x74, 0x03, -0xF0, 0x90, 0xA1, 0x17, 0x74, 0x08, 0xF0, 0xE5, 0x65, 0x04, 0x54, 0x0F, 0xF5, 0x66, 0xE4, 0xF5, -0x63, 0xE5, 0x66, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, -0xE5, 0x82, 0x25, 0x63, 0x12, 0x56, 0x0E, 0xE0, 0xFF, 0x74, 0x0B, 0x25, 0x63, 0xF5, 0x82, 0xE4, -0x34, 0xA1, 0xF5, 0x83, 0xEF, 0xF0, 0x05, 0x63, 0xE5, 0x63, 0xB4, 0x08, 0xD4, 0x7B, 0x01, 0x7A, -0xA1, 0x79, 0x09, 0x12, 0x8A, 0xE4, 0xE5, 0x65, 0x04, 0x54, 0x0F, 0xF5, 0x65, 0xB4, 0x0F, 0x03, -0xE4, 0xF5, 0x65, 0x90, 0x04, 0x7F, 0xE5, 0x65, 0xF0, 0x90, 0xA1, 0x08, 0xE0, 0x7F, 0x04, 0x70, -0x03, 0x02, 0x86, 0x68, 0x12, 0x8B, 0xCF, 0x22, 0xE4, 0xFF, 0x90, 0xA0, 0x5B, 0xEF, 0xF0, 0xE4, -0xA3, 0xF0, 0x12, 0xAA, 0x0B, 0x50, 0x2B, 0xF1, 0xAB, 0xE4, 0xF0, 0x12, 0xA3, 0x67, 0x90, 0xA0, -0x5C, 0x30, 0xE7, 0x07, 0x12, 0xA9, 0xA8, 0xE4, 0xF0, 0x80, 0x0F, 0xE0, 0xFF, 0xF1, 0xD6, 0x90, -0xA0, 0x5C, 0xE0, 0x24, 0x5D, 0xF1, 0xAE, 0x74, 0x01, 0xF0, 0x90, 0xA0, 0x5C, 0xE0, 0x04, 0xF0, -0x80, 0xD0, 0x7F, 0x0C, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0xE4, 0x90, 0xA0, 0x5C, 0xF0, 0x12, 0xAA, -0x0B, 0x40, 0x02, 0xE1, 0xAA, 0xF1, 0xAB, 0xE0, 0x60, 0x78, 0xF1, 0xCD, 0x90, 0x81, 0x06, 0xF1, -0xC4, 0xEF, 0x90, 0x81, 0x07, 0x12, 0xA9, 0x90, 0xFC, 0x12, 0x77, 0xD7, 0xEE, 0x12, 0xAA, 0x71, -0xEC, 0x90, 0x81, 0x0A, 0xF1, 0xC4, 0xEC, 0x90, 0x81, 0x0B, 0x12, 0xA9, 0x90, 0x75, 0xF0, 0x0A, -0xF1, 0xB6, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x7F, 0x01, 0x90, 0xA0, 0x5C, 0xE0, 0xFE, 0x75, 0xF0, -0x10, 0x90, 0x81, 0x0B, 0x12, 0x56, 0x08, 0xE0, 0xFD, 0x75, 0xF0, 0x0A, 0xEE, 0xF1, 0xB6, 0x75, -0xF0, 0x02, 0xEF, 0x12, 0xA3, 0x55, 0xED, 0xF0, 0x0F, 0xEF, 0xB4, 0x05, 0xDC, 0xF1, 0xCD, 0x90, -0x81, 0x09, 0x12, 0x45, 0xA9, 0xE0, 0xFE, 0x12, 0xA3, 0x5C, 0xEE, 0xF0, 0x90, 0xA0, 0x5C, 0xE0, -0xFF, 0x90, 0xA0, 0x5B, 0xE0, 0xFD, 0x12, 0xA2, 0xFC, 0x90, 0xA0, 0x5C, 0x12, 0xA9, 0xA8, 0x74, -0x01, 0xF0, 0x90, 0xA0, 0x5C, 0xE0, 0x04, 0xF0, 0xE1, 0x1E, 0x22, 0x74, 0x5D, 0x2F, 0xF5, 0x82, -0xE4, 0x34, 0xA0, 0xF5, 0x83, 0x22, 0x90, 0x8D, 0x01, 0x02, 0x45, 0xA9, 0x90, 0x81, 0x00, 0x12, -0x45, 0xA9, 0xE0, 0x22, 0x12, 0x45, 0xA9, 0xE0, 0xFD, 0x75, 0xF0, 0x10, 0x22, 0x90, 0xA0, 0x5C, -0xE0, 0xFF, 0x75, 0xF0, 0x10, 0x22, 0x12, 0xA3, 0x67, 0x44, 0x40, 0xF0, 0x22, 0xFF, 0xEE, 0x55, -0x83, 0xFE, 0xEF, 0x55, 0x82, 0x4E, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, -0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, -0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xE7, 0xF0, 0x74, 0x7F, 0xA3, 0xF0, 0x12, 0xA0, -0x79, 0xE5, 0x21, 0x30, 0xE1, 0x03, 0x12, 0xA1, 0x13, 0xE5, 0x21, 0x30, 0xE2, 0x03, 0x12, 0x6F, -0x31, 0xE5, 0x21, 0x30, 0xE5, 0x02, 0x11, 0xA4, 0xE5, 0x22, 0x30, 0xE0, 0x03, 0x12, 0x95, 0x5B, -0xE5, 0x23, 0x30, 0xE1, 0x03, 0x12, 0xA1, 0x67, 0xE5, 0x23, 0x30, 0xE0, 0x03, 0x12, 0xA1, 0x1F, -0xE5, 0x23, 0x30, 0xE3, 0x02, 0xF1, 0xB3, 0xE5, 0x23, 0x30, 0xE2, 0x0A, 0x12, 0xA1, 0xB0, 0x90, -0x07, 0x8F, 0xE0, 0x44, 0x10, 0xF0, 0xE5, 0x24, 0x30, 0xE1, 0x04, 0x7F, 0x04, 0xD1, 0x68, 0xE5, -0x24, 0x30, 0xE4, 0x02, 0x11, 0xB7, 0xE5, 0x24, 0x30, 0xE5, 0x03, 0x12, 0x6E, 0x35, 0xE5, 0x24, -0x30, 0xE6, 0x03, 0x12, 0x6E, 0x62, 0xE5, 0x24, 0x30, 0xE7, 0x03, 0x12, 0x67, 0xD0, 0x74, 0xE7, -0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x7F, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, +0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xDE, +0xF0, 0x74, 0x87, 0xA3, 0xF0, 0x12, 0xA2, 0x62, 0xE5, 0x21, 0x30, 0xE1, 0x02, 0x11, 0xC1, 0xE5, +0x21, 0x30, 0xE2, 0x02, 0x31, 0x46, 0xE5, 0x21, 0x30, 0xE5, 0x02, 0x11, 0x97, 0xE5, 0x22, 0x30, +0xE0, 0x02, 0x51, 0xD8, 0xE5, 0x23, 0x30, 0xE1, 0x03, 0x12, 0xA4, 0x29, 0xE5, 0x23, 0x30, 0xE0, +0x03, 0x12, 0xA3, 0x57, 0xE5, 0x23, 0x30, 0xE3, 0x02, 0xF1, 0xB3, 0xE5, 0x23, 0x30, 0xE2, 0x09, +0x31, 0xB6, 0x90, 0x07, 0x8F, 0xE0, 0x44, 0x10, 0xF0, 0xE5, 0x24, 0x30, 0xE1, 0x05, 0x7F, 0x04, +0x12, 0x6F, 0x57, 0xE5, 0x24, 0x30, 0xE4, 0x03, 0x12, 0x82, 0x6F, 0xE5, 0x24, 0x30, 0xE5, 0x02, +0x31, 0x87, 0xE5, 0x24, 0x30, 0xE6, 0x03, 0x12, 0xA4, 0x72, 0xE5, 0x24, 0x30, 0xE7, 0x02, 0x31, +0x2E, 0x74, 0xDE, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x87, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, +0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, +0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0xA0, 0xC1, 0xE0, 0x30, 0xE0, 0x0A, 0x11, 0xA9, +0xE4, 0x90, 0xA0, 0xC3, 0xF0, 0x12, 0x48, 0x05, 0x22, 0x7D, 0x20, 0xE4, 0xFF, 0x74, 0x1D, 0x12, +0xAD, 0x31, 0xFE, 0xF6, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0xEE, 0xF0, +0x22, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x02, 0x91, 0x97, 0x02, 0x48, 0x61, 0x7D, 0x03, 0x7F, 0x02, +0x74, 0x1D, 0x2F, 0xF8, 0xE6, 0x4D, 0x80, 0xDA, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, +0x07, 0xEF, 0x54, 0x01, 0xFE, 0x90, 0xA0, 0x52, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0xEF, 0x64, 0x01, +0x70, 0x21, 0x90, 0x01, 0x53, 0xF0, 0x90, 0xA0, 0x54, 0xE0, 0x60, 0x0B, 0x7D, 0x10, 0x7F, 0x03, +0x11, 0xD0, 0x12, 0x97, 0x85, 0x80, 0x18, 0x31, 0x24, 0x11, 0xAD, 0x12, 0x5F, 0xA1, 0x12, 0x5E, +0xF0, 0x80, 0x0C, 0x31, 0x24, 0x11, 0xD0, 0x12, 0x5C, 0xCD, 0xF1, 0xC2, 0x12, 0x5C, 0x99, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0x53, 0x74, 0x03, 0xF0, 0x7D, 0x10, 0xFF, 0x22, 0x90, 0xA0, +0x7A, 0xE0, 0x30, 0xE0, 0x05, 0x12, 0x67, 0xA3, 0x80, 0x02, 0xF1, 0x3F, 0x90, 0xA0, 0xAD, 0xE0, +0x30, 0xE0, 0x02, 0x31, 0xE8, 0x22, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x14, 0x90, 0x06, 0x92, 0xE0, +0x30, 0xE1, 0x03, 0x02, 0xA8, 0xE1, 0x90, 0x9F, 0xA3, 0xE0, 0x54, 0xF7, 0xF0, 0x12, 0x68, 0x44, +0x22, 0xF1, 0xC9, 0x90, 0xA0, 0x52, 0x12, 0x6F, 0x44, 0x12, 0x6A, 0x86, 0x90, 0xA0, 0x53, 0x12, +0x56, 0xDD, 0x90, 0xA0, 0x54, 0xF0, 0x90, 0xA0, 0x53, 0xE0, 0x90, 0xA0, 0x55, 0xF0, 0x90, 0xA0, +0x52, 0xE0, 0x54, 0x01, 0xFF, 0x01, 0xD8, 0x90, 0x9F, 0xA3, 0x12, 0x6F, 0xA4, 0x30, 0xE0, 0x25, +0xEF, 0x54, 0xBF, 0x12, 0xA5, 0x05, 0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x04, 0xE0, +0x54, 0xFE, 0xF0, 0x90, 0xA0, 0x65, 0xF1, 0xB4, 0x30, 0xE0, 0x07, 0x7D, 0x01, 0x7F, 0x0C, 0x02, +0x5A, 0xA1, 0x12, 0x68, 0x44, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA0, 0xAD, +0xE0, 0x30, 0xE0, 0x1F, 0x90, 0xA0, 0xB2, 0xE0, 0xB4, 0x01, 0x0C, 0xA3, 0xE0, 0xB4, 0x01, 0x13, +0x74, 0x02, 0xF0, 0x51, 0x53, 0x80, 0x0C, 0x90, 0xA0, 0xB2, 0xE0, 0xB4, 0x02, 0x05, 0x74, 0x03, +0xF0, 0x31, 0xE8, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0xA0, 0xB4, 0xE0, 0xB4, 0x01, 0x02, 0x80, 0x43, 0x90, 0xA0, 0xB4, 0xE0, 0xB4, 0x02, 0x11, 0x51, +0x53, 0x7F, 0x01, 0x51, 0x84, 0x12, 0x66, 0xFE, 0x90, 0xA0, 0xB4, 0x74, 0x03, 0xF0, 0x80, 0x3E, +0x90, 0xA0, 0xB4, 0xE0, 0x64, 0x03, 0x70, 0x1C, 0x90, 0xA0, 0xB7, 0x51, 0x56, 0xE4, 0xFF, 0x51, +0x84, 0x12, 0x66, 0xFE, 0x51, 0x7A, 0xE4, 0xFB, 0xFD, 0x12, 0x4E, 0x54, 0x90, 0xA0, 0xB4, 0x74, +0x04, 0xF0, 0x80, 0x1A, 0x90, 0xA0, 0xB4, 0xE0, 0xB4, 0x04, 0x13, 0x51, 0x7A, 0x7B, 0x01, 0x7D, +0x01, 0x12, 0x4E, 0x54, 0x90, 0xA0, 0xB4, 0x74, 0x02, 0xF0, 0x90, 0xA0, 0xB2, 0xF0, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0x90, 0xA0, 0xB9, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xAD, 0x07, 0xEE, 0xFF, 0x90, +0x01, 0x6F, 0xE4, 0xF0, 0x8F, 0x35, 0xAF, 0x05, 0x8F, 0x36, 0xFB, 0xFD, 0x7F, 0x6C, 0x7E, 0x01, +0x12, 0x3C, 0xB1, 0x90, 0x01, 0x6F, 0x74, 0x05, 0xF0, 0x22, 0x90, 0xA0, 0xAD, 0xE0, 0xC3, 0x13, +0x54, 0x03, 0xFF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xEF, 0xB4, 0x03, 0x10, 0x90, +0xA0, 0x62, 0x12, 0x4F, 0xD3, 0x90, 0x06, 0xCC, 0x30, 0xE0, 0x35, 0xE4, 0xF0, 0x80, 0x34, 0x90, +0xA0, 0x63, 0xE0, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x0C, 0xEF, 0x90, 0x06, 0xCC, 0x70, 0x03, 0xF0, +0x80, 0x03, 0x74, 0x03, 0xF0, 0x90, 0xA0, 0xAD, 0xE0, 0x30, 0xE0, 0x17, 0xC4, 0x54, 0x0F, 0x30, +0xE0, 0x0B, 0xEF, 0x90, 0x06, 0xCC, 0x70, 0x03, 0xF0, 0x80, 0x08, 0x80, 0x03, 0x90, 0x06, 0xCC, +0x74, 0x03, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0xA5, 0x0E, 0x90, 0xA1, 0x2B, 0xEF, 0xF0, +0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x5A, 0x1E, 0x90, 0xA1, +0x2B, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80, 0x06, +0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0x91, 0xF9, 0x90, 0x9F, 0xC0, 0xE0, 0xFB, 0xAC, 0x07, 0x90, +0x9F, 0xA3, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x9F, 0xDD, 0xE0, 0x24, 0x04, 0x90, 0x9F, 0xBC, 0xF0, +0x90, 0x9F, 0xDD, 0xE0, 0x24, 0x03, 0x90, 0x9F, 0xBB, 0xF0, 0x80, 0x0B, 0x90, 0x9F, 0xBC, 0x74, +0x02, 0xF0, 0x90, 0x9F, 0xBB, 0x14, 0xF0, 0x90, 0x9F, 0xBB, 0xE0, 0xFA, 0x90, 0x9F, 0xBA, 0xE0, +0xD3, 0x9A, 0x50, 0x09, 0x90, 0x9F, 0xAF, 0xEB, 0x71, 0x70, 0x2C, 0x80, 0x0B, 0xAD, 0x02, 0xC3, +0xED, 0x9D, 0x2B, 0x90, 0x9F, 0xAF, 0x71, 0x70, 0x90, 0x9F, 0xBF, 0xF0, 0x90, 0x9F, 0xBF, 0xE0, +0xFF, 0x7E, 0x00, 0x90, 0x9F, 0xB3, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x05, 0x58, 0xF0, 0x22, +0xF0, 0x90, 0x9F, 0xBC, 0xE0, 0xC3, 0x9D, 0x22, 0xE4, 0xFD, 0xF9, 0xFC, 0x90, 0x05, 0x62, 0xE0, +0xFE, 0x90, 0x05, 0x61, 0xE0, 0xFB, 0xEB, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, +0xFF, 0xEE, 0x54, 0x3F, 0x90, 0x9F, 0xE0, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, +0xFF, 0x90, 0x9F, 0xE0, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xC3, 0x9F, 0xEA, 0x9E, 0x40, 0x21, 0xEB, +0x9F, 0xFF, 0x90, 0x9F, 0xBF, 0xE0, 0xFE, 0xC3, 0x74, 0x0A, 0x9E, 0x2F, 0xF9, 0xC3, 0x94, 0x19, +0x50, 0x0E, 0x74, 0xC4, 0x29, 0x91, 0x64, 0xE0, 0x04, 0xF0, 0x90, 0x9F, 0xBD, 0xE0, 0x04, 0xF0, +0x90, 0x9F, 0xBD, 0xE0, 0xC3, 0x94, 0x64, 0x50, 0x02, 0x81, 0x60, 0xE4, 0xFC, 0xFD, 0x91, 0x61, +0xE0, 0x2C, 0xFC, 0xD3, 0x94, 0x05, 0x40, 0x07, 0x90, 0xA1, 0x1D, 0xED, 0xF0, 0x80, 0x05, 0x0D, +0xED, 0xB4, 0x19, 0xEA, 0xE4, 0xFC, 0xFD, 0x91, 0x61, 0xE0, 0x2C, 0xFC, 0xD3, 0x94, 0x5F, 0x40, +0x07, 0x90, 0xA1, 0x1E, 0xED, 0xF0, 0x80, 0x05, 0x0D, 0xED, 0xB4, 0x19, 0xEA, 0x90, 0xA1, 0x1D, +0xE0, 0x90, 0x9F, 0xC2, 0xF0, 0x90, 0xA1, 0x1E, 0xE0, 0x90, 0x9F, 0xC3, 0x91, 0x6C, 0x94, 0x0B, +0x40, 0x0A, 0xEF, 0x24, 0xF6, 0x90, 0x9F, 0xBA, 0xF0, 0xE4, 0x80, 0x09, 0xE4, 0x90, 0x9F, 0xBA, +0x91, 0x6C, 0x74, 0x0A, 0x9F, 0x90, 0x9F, 0xB9, 0xF0, 0x90, 0x9F, 0xC2, 0xE0, 0xFF, 0xA3, 0xE0, +0xC3, 0x9F, 0x90, 0x9F, 0xC0, 0xF0, 0xC3, 0x94, 0x08, 0x50, 0x03, 0x74, 0x08, 0xF0, 0x90, 0x9F, +0xBA, 0xE0, 0xFD, 0x90, 0x9F, 0xC0, 0xE0, 0xFB, 0xE4, 0xFF, 0x71, 0x0D, 0xE4, 0xFF, 0xF1, 0x8A, +0x22, 0x74, 0xC4, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x9F, 0xF5, 0x83, 0x22, 0xF0, 0x90, 0x9F, 0xC2, +0xE0, 0xFF, 0xC3, 0x22, 0xF1, 0x0B, 0x40, 0x1E, 0x90, 0x9F, 0xC1, 0xE0, 0x04, 0xF0, 0xE0, 0xFF, +0x94, 0x04, 0x50, 0x12, 0x90, 0x9F, 0xB9, 0xEF, 0xF0, 0x25, 0xE0, 0x24, 0x08, 0x90, 0x9F, 0xC0, +0xF0, 0xFB, 0x91, 0xF9, 0x71, 0x0D, 0x22, 0x90, 0x9F, 0xA4, 0xE0, 0x12, 0x5E, 0xCD, 0x30, 0xE0, +0x0B, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x02, 0xF1, 0xBB, 0xB1, 0x02, 0x30, 0xE0, +0x08, 0xF1, 0x7E, 0x54, 0x07, 0x70, 0x39, 0x80, 0x34, 0xD1, 0xFE, 0x40, 0x30, 0x12, 0x5F, 0x8C, +0x64, 0x01, 0x70, 0x2C, 0x12, 0x69, 0x3A, 0x70, 0x04, 0x91, 0x74, 0x80, 0x24, 0x91, 0x74, 0x90, +0x9F, 0xB1, 0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94, 0x02, 0x40, 0x09, 0x91, 0xF1, 0xE4, 0x90, 0x9F, +0xB1, 0xF0, 0x80, 0x03, 0x12, 0x5F, 0xB7, 0xE4, 0x90, 0x9F, 0xB0, 0xF0, 0x22, 0x12, 0x68, 0x44, +0x22, 0x90, 0x9F, 0xA4, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x90, 0x9F, 0xB9, 0xE0, 0xFF, 0xA3, 0xE0, +0xFD, 0x22, 0x90, 0x9F, 0xA3, 0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x12, 0x4F, 0xD0, 0x20, +0xE0, 0x02, 0xC1, 0xB9, 0x90, 0xA0, 0x67, 0xE0, 0x64, 0x01, 0x70, 0x2A, 0x90, 0x06, 0x92, 0xE0, +0x20, 0xE2, 0x06, 0x90, 0x04, 0xE3, 0xE0, 0x60, 0x18, 0xD1, 0xC0, 0xD1, 0xC7, 0x90, 0xA0, 0x6B, +0xE0, 0x75, 0xF0, 0x03, 0x84, 0xFF, 0x90, 0xA0, 0x74, 0xE0, 0xB5, 0x07, 0x02, 0x80, 0x02, 0xC1, +0xA3, 0xD1, 0xD6, 0x04, 0xF0, 0x22, 0x90, 0xA0, 0x67, 0xE0, 0x64, 0x04, 0x70, 0x27, 0x90, 0x06, +0x92, 0xE0, 0x20, 0xE2, 0x06, 0x90, 0x04, 0xE3, 0xE0, 0x60, 0x14, 0xD1, 0xC0, 0xD1, 0xC7, 0x90, +0xA0, 0x6A, 0xE0, 0xFF, 0x90, 0xA0, 0x74, 0xE0, 0xB5, 0x07, 0x02, 0x80, 0x02, 0xC1, 0xA3, 0xD1, +0xD6, 0x74, 0x04, 0xF0, 0x22, 0x90, 0xA0, 0x67, 0xE0, 0x64, 0x06, 0x60, 0x02, 0xC1, 0x22, 0xF1, +0x17, 0x50, 0x08, 0x90, 0xA0, 0x75, 0xE0, 0x94, 0x03, 0x40, 0x1B, 0x12, 0x85, 0xA8, 0x90, 0xA0, +0x72, 0x30, 0xE0, 0x05, 0x74, 0x05, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0xE4, 0x90, 0xA0, 0x67, +0xF0, 0x90, 0xA0, 0x75, 0xF0, 0x22, 0x90, 0xA0, 0x66, 0xB1, 0x05, 0x30, 0xE0, 0x40, 0xEF, 0x54, +0xFB, 0xF0, 0xE4, 0xA3, 0x12, 0x85, 0xA7, 0x30, 0xE0, 0x0B, 0x90, 0xA0, 0x84, 0xE0, 0x20, 0xE0, +0x02, 0xC1, 0x59, 0xC1, 0x4C, 0xF1, 0x17, 0x40, 0x0B, 0x90, 0xA0, 0x84, 0xE0, 0x30, 0xE0, 0x02, +0x80, 0x7A, 0xC1, 0x59, 0x90, 0xA0, 0x84, 0xE0, 0x30, 0xE0, 0x0C, 0xD1, 0xBA, 0xE4, 0x90, 0xA0, +0x74, 0xF0, 0x90, 0xA2, 0x15, 0x80, 0x7D, 0x90, 0xA0, 0x72, 0x74, 0x02, 0xF0, 0x22, 0x12, 0x4C, +0x80, 0x90, 0xA0, 0x75, 0xE0, 0x04, 0xF0, 0x7F, 0x03, 0x12, 0x66, 0xEC, 0xF1, 0x17, 0x50, 0x0A, +0x90, 0xA0, 0x75, 0xE0, 0x94, 0x03, 0x50, 0x02, 0xC1, 0xB9, 0x7F, 0x03, 0x12, 0x62, 0xC3, 0x90, +0x05, 0x22, 0xE0, 0x44, 0x10, 0xFF, 0x7D, 0x03, 0x12, 0x49, 0x22, 0x90, 0x04, 0x9C, 0xE0, 0x04, +0xF0, 0x22, 0x90, 0xA0, 0x67, 0xE0, 0x64, 0x07, 0x70, 0x3D, 0x90, 0xA0, 0x75, 0xE0, 0xB4, 0x04, +0x05, 0x12, 0x6F, 0xD1, 0x80, 0x67, 0x90, 0xA0, 0x66, 0xB1, 0x05, 0x30, 0xE0, 0x1E, 0xEF, 0x54, +0xFB, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0xA0, 0x84, 0xE0, 0x30, 0xE0, 0x0D, 0xD1, 0xBA, 0xE4, 0x90, +0xA0, 0x74, 0xF0, 0x90, 0xA2, 0x15, 0x04, 0x80, 0x0B, 0x02, 0x6F, 0xD1, 0x12, 0x4C, 0x80, 0x90, +0xA0, 0x75, 0xE0, 0x04, 0xF0, 0x80, 0x3C, 0x90, 0xA0, 0x67, 0xE0, 0x64, 0x09, 0x70, 0x4A, 0x90, +0xA0, 0x66, 0xE0, 0x30, 0xE0, 0x0B, 0x12, 0x6F, 0xD1, 0x90, 0xA0, 0x66, 0xE0, 0x54, 0xFE, 0xF0, +0x22, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE2, 0x20, 0x74, 0x04, 0xF0, 0xD1, 0xC7, 0xE0, 0xB4, 0x02, +0x12, 0xD1, 0xCE, 0x60, 0x05, 0x74, 0x05, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0xE4, 0x90, 0xA0, +0x67, 0xF0, 0x22, 0x7F, 0x03, 0x02, 0x66, 0xEC, 0xD1, 0xCE, 0x60, 0x05, 0x74, 0x05, 0xF0, 0x80, +0x03, 0x74, 0x02, 0xF0, 0xE4, 0x90, 0xA0, 0x67, 0xF0, 0x22, 0x90, 0xA0, 0x67, 0x74, 0x09, 0xF0, +0x90, 0x06, 0x92, 0x74, 0x04, 0xF0, 0x22, 0x90, 0xA0, 0x74, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0xA2, +0x15, 0xE0, 0x90, 0xA0, 0x72, 0x22, 0xE4, 0x90, 0xA0, 0x67, 0xF0, 0x90, 0xA0, 0x72, 0x22, 0x90, +0x01, 0x57, 0xE0, 0x60, 0x18, 0x12, 0x82, 0xC7, 0xB1, 0x02, 0x30, 0xE0, 0x02, 0xE1, 0x7E, 0xD1, +0xFE, 0x40, 0x0A, 0xE4, 0xFF, 0x12, 0x5F, 0x2F, 0xBF, 0x01, 0x02, 0x91, 0xF1, 0x22, 0x90, 0x9F, +0xB0, 0xE0, 0x04, 0xF0, 0x90, 0x9F, 0xAB, 0xE0, 0x54, 0xEF, 0xF0, 0x90, 0xA0, 0x4B, 0xE0, 0xFF, +0x90, 0x9F, 0xB0, 0xE0, 0xD3, 0x9F, 0x22, 0x90, 0xA0, 0x75, 0xE0, 0xFF, 0x90, 0xA0, 0x74, 0xE0, +0x2F, 0xFF, 0xE4, 0x33, 0xFE, 0x7C, 0x00, 0x7D, 0x03, 0x12, 0x07, 0x03, 0x90, 0xA0, 0x6B, 0xE0, +0x2F, 0xFF, 0xEC, 0x3E, 0xFE, 0xC3, 0xEF, 0x94, 0x41, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x22, 0x90, +0xA0, 0x5F, 0xE0, 0x30, 0xE0, 0x37, 0xB1, 0x0C, 0x90, 0xA0, 0x72, 0xE0, 0xFF, 0xB4, 0x01, 0x02, +0x80, 0x1D, 0x90, 0xA0, 0x72, 0xE0, 0xFF, 0xB4, 0x02, 0x02, 0x80, 0x1E, 0x90, 0xA0, 0x72, 0xE0, +0xFF, 0xB4, 0x03, 0x03, 0x02, 0x65, 0x1D, 0x90, 0xA0, 0x72, 0xE0, 0xFF, 0xB4, 0x04, 0x03, 0x02, +0x85, 0xB0, 0x90, 0xA0, 0x72, 0xE0, 0xFF, 0xB4, 0x05, 0x03, 0x12, 0x9A, 0x62, 0x22, 0xEF, 0x54, +0xFB, 0xF0, 0x90, 0x9F, 0xAB, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0xE4, 0xFE, 0x74, 0xC4, 0x2E, 0x91, +0x64, 0xE4, 0xF0, 0x0E, 0xEE, 0xB4, 0x19, 0xF4, 0xE4, 0x90, 0x9F, 0xBD, 0xF0, 0x90, 0x9F, 0xC1, +0xF0, 0x90, 0x9F, 0xB9, 0xF0, 0xEF, 0xB4, 0x01, 0x09, 0x90, 0x9F, 0xC2, 0x74, 0x19, 0xF0, 0xE4, +0xA3, 0xF0, 0x22, 0x22, 0xE0, 0xFF, 0xC4, 0x13, 0x54, 0x07, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0x02, +0x5F, 0xAB, 0x7D, 0x01, 0x7F, 0x02, 0x02, 0x5C, 0xD1, 0x12, 0x06, 0x89, 0xFF, 0x54, 0x01, 0xFE, +0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, +0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, +0xC4, 0x74, 0xD1, 0xF0, 0x74, 0x8F, 0xA3, 0xF0, 0x12, 0x90, 0x24, 0x53, 0x91, 0xBF, 0x74, 0xD1, +0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x8F, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, -0xF0, 0xD0, 0xE0, 0x32, 0x90, 0xA0, 0x2C, 0xE0, 0x30, 0xE0, 0x0B, 0x12, 0x6F, 0x6B, 0xE4, 0x90, -0xA0, 0x2E, 0xF0, 0x12, 0x48, 0x00, 0x22, 0x12, 0x90, 0x13, 0x12, 0x97, 0x5A, 0xF1, 0xC1, 0x11, -0xC4, 0x02, 0x5F, 0x29, 0x90, 0x9F, 0xCA, 0xE0, 0x30, 0xE0, 0x04, 0xE4, 0xFF, 0x11, 0xD0, 0x22, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xC8, 0xEF, 0xF0, 0xA3, 0x74, 0x02, 0xF0, -0xE4, 0xFF, 0x12, 0x97, 0xD0, 0x90, 0x9F, 0xCE, 0x12, 0x6E, 0xBB, 0x30, 0xE0, 0x03, 0x12, 0x5F, -0x71, 0x90, 0x9F, 0xCE, 0xE0, 0x30, 0xE0, 0x04, 0x7F, 0x01, 0x80, 0x37, 0x90, 0x9F, 0xCA, 0x12, -0x4F, 0xD2, 0x30, 0xE0, 0x04, 0x7F, 0x0D, 0x80, 0x2A, 0x90, 0x9F, 0xCD, 0xE0, 0xFF, 0xC4, 0x54, -0x0F, 0x30, 0xE0, 0x10, 0xEF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x04, 0x7F, 0x09, 0x80, 0x13, -0x7F, 0x03, 0x80, 0x0F, 0x90, 0x9F, 0xCD, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x04, 0x7F, 0x03, 0x80, -0x02, 0x7F, 0x09, 0x12, 0x62, 0x14, 0x90, 0xA1, 0xC8, 0xE0, 0x64, 0x03, 0x70, 0x6A, 0x12, 0x4F, -0xCF, 0x30, 0xE0, 0x5F, 0x90, 0x9F, 0xD5, 0xE0, 0xFF, 0x90, 0x9F, 0xE0, 0xE0, 0xFE, 0xD3, 0x9F, -0x40, 0x37, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0xFF, 0x90, 0x9F, 0xD7, 0xE0, 0xFE, 0xC3, 0xEF, 0x9E, -0xFF, 0x24, 0x03, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x9F, 0xCC, 0xE0, 0xFE, 0xD3, 0x9D, 0xEC, 0x12, -0x77, 0x9E, 0x40, 0x08, 0xEE, 0x9F, 0x90, 0xA1, 0xCB, 0xF0, 0x80, 0x06, 0x90, 0xA1, 0xCB, 0x74, -0x03, 0xF0, 0x90, 0xA1, 0xCB, 0x51, 0xAE, 0x80, 0x13, 0x90, 0x9F, 0xD8, 0xE0, 0xFF, 0x51, 0x9C, -0x90, 0x9F, 0xD3, 0x74, 0x04, 0xF0, 0xE4, 0x90, 0x9F, 0xDE, 0x91, 0x6A, 0xE4, 0x90, 0x9F, 0xE0, -0xF0, 0x80, 0x05, 0x90, 0x9F, 0xCC, 0x51, 0xAE, 0x90, 0x9F, 0xCA, 0xE0, 0x12, 0x56, 0xCD, 0x30, -0xE0, 0x07, 0xE4, 0x90, 0xA1, 0xCA, 0xF0, 0x80, 0x06, 0x90, 0xA1, 0xCA, 0x74, 0x01, 0xF0, 0x12, -0xAA, 0x38, 0x20, 0xE0, 0x13, 0x90, 0xA0, 0x0C, 0xE0, 0x60, 0x07, 0xE4, 0x90, 0xA1, 0xC9, 0xF0, -0x80, 0x06, 0x90, 0xA1, 0xC9, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0xC9, 0x12, 0x62, 0xC8, 0x90, 0x9F, -0xDD, 0x74, 0x01, 0xF0, 0xD1, 0x1B, 0x30, 0xE0, 0x0D, 0x90, 0xA1, 0xC8, 0xE0, 0x70, 0x3A, 0xFD, -0xFF, 0x12, 0x49, 0x1D, 0x80, 0x33, 0xD1, 0x13, 0x30, 0xE0, 0x1A, 0x90, 0x9F, 0xD1, 0xE0, 0x44, -0x20, 0xF0, 0x90, 0x9F, 0xBC, 0xE0, 0x60, 0x04, 0x7D, 0x01, 0x80, 0x18, 0x12, 0x5C, 0x9B, 0x7D, -0x01, 0x7F, 0x0C, 0x80, 0x11, 0x90, 0xA1, 0xC8, 0xE0, 0xB4, 0x03, 0x0D, 0x90, 0x9F, 0x17, 0xE0, -0x60, 0x07, 0xE4, 0xFD, 0x7F, 0x04, 0x12, 0x5A, 0xA8, 0x90, 0x9F, 0xBC, 0xE0, 0x60, 0x18, 0x90, -0xA1, 0xC8, 0xE0, 0x70, 0x04, 0x7D, 0x04, 0x80, 0x0A, 0x90, 0xA1, 0xC8, 0xE0, 0x64, 0x03, 0x70, -0x2C, 0x7D, 0x0B, 0x7F, 0x6F, 0x80, 0x23, 0x90, 0xA1, 0xC8, 0xE0, 0x70, 0x04, 0xFD, 0xFF, 0x80, -0x19, 0x90, 0xA1, 0xC8, 0xE0, 0xB4, 0x03, 0x15, 0xD1, 0x24, 0x20, 0xE0, 0x0A, 0xEF, 0x13, 0x13, -0x54, 0x3F, 0x30, 0xE0, 0x02, 0xF1, 0xD8, 0xE4, 0xFD, 0xFF, 0x12, 0x49, 0x1D, 0x90, 0x9F, 0xCD, -0xE0, 0x12, 0x56, 0xCD, 0x30, 0xE0, 0x05, 0x7F, 0x01, 0x12, 0x8F, 0xCD, 0x90, 0x9F, 0xCE, 0xE0, -0xC3, 0x13, 0x30, 0xE0, 0x0E, 0x90, 0x06, 0xCD, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x06, 0xCF, 0xE0, -0x44, 0x10, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xC3, 0x9F, 0xFF, 0xE4, 0x90, 0xA1, 0xB1, -0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x6C, 0x7E, 0x01, 0x02, 0x48, 0x2F, 0xE0, 0xFF, -0x51, 0x9C, 0x90, 0x9F, 0xDE, 0xE0, 0x04, 0xF0, 0x22, 0x12, 0x4F, 0xCF, 0x20, 0xE0, 0x02, 0x81, -0x64, 0x90, 0x9F, 0xD3, 0xE0, 0x64, 0x01, 0x70, 0x2A, 0x90, 0x06, 0x92, 0xE0, 0x20, 0xE2, 0x06, -0x90, 0x04, 0xE3, 0xE0, 0x60, 0x18, 0x91, 0x6B, 0x91, 0x72, 0x90, 0x9F, 0xD7, 0xE0, 0x75, 0xF0, -0x03, 0x84, 0xFF, 0x90, 0x9F, 0xE0, 0xE0, 0xB5, 0x07, 0x02, 0x80, 0x02, 0x81, 0x4F, 0xB1, 0xCD, -0x04, 0xF0, 0x22, 0x90, 0x9F, 0xD3, 0xE0, 0x64, 0x04, 0x70, 0x27, 0x90, 0x06, 0x92, 0xE0, 0x20, -0xE2, 0x06, 0x90, 0x04, 0xE3, 0xE0, 0x60, 0x14, 0x91, 0x6B, 0x91, 0x72, 0x90, 0x9F, 0xD6, 0xE0, -0xFF, 0x90, 0x9F, 0xE0, 0xE0, 0xB5, 0x07, 0x02, 0x80, 0x02, 0x81, 0x4F, 0xB1, 0xCD, 0x74, 0x04, -0xF0, 0x22, 0x90, 0x9F, 0xD3, 0xE0, 0x64, 0x06, 0x60, 0x02, 0x61, 0xCD, 0x91, 0x79, 0x50, 0x08, -0x90, 0x9F, 0xE1, 0xE0, 0x94, 0x03, 0x40, 0x1A, 0x91, 0xAA, 0x90, 0x9F, 0xDE, 0x30, 0xE0, 0x05, -0x74, 0x05, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0xE4, 0x90, 0x9F, 0xD3, 0xF0, 0x90, 0x9F, 0xE1, -0xF0, 0x22, 0x90, 0x9F, 0xD2, 0x12, 0x6E, 0xBB, 0x30, 0xE0, 0x3F, 0xEF, 0x54, 0xFB, 0xF0, 0xE4, -0xA3, 0x91, 0xA9, 0x30, 0xE0, 0x0B, 0x90, 0x9F, 0xF0, 0xE0, 0x20, 0xE0, 0x02, 0x81, 0x05, 0x61, -0xF8, 0x91, 0x79, 0x40, 0x0B, 0x90, 0x9F, 0xF0, 0xE0, 0x30, 0xE0, 0x02, 0x80, 0x7A, 0x81, 0x05, -0x90, 0x9F, 0xF0, 0xE0, 0x30, 0xE0, 0x0C, 0x91, 0x65, 0xE4, 0x90, 0x9F, 0xE0, 0xF0, 0x90, 0xA1, -0xED, 0x80, 0x7D, 0x90, 0x9F, 0xDE, 0x74, 0x02, 0xF0, 0x22, 0x12, 0x4C, 0x7D, 0x90, 0x9F, 0xE1, -0xE0, 0x04, 0xF0, 0x7F, 0x03, 0x51, 0x9C, 0x91, 0x79, 0x50, 0x0A, 0x90, 0x9F, 0xE1, 0xE0, 0x94, -0x03, 0x50, 0x02, 0x81, 0x64, 0x7F, 0x03, 0x12, 0x62, 0x14, 0x90, 0x05, 0x22, 0xE0, 0x44, 0x10, -0xFF, 0x7D, 0x03, 0x12, 0x49, 0x1D, 0x90, 0x04, 0x9C, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x9F, 0xD3, -0xE0, 0x64, 0x07, 0x70, 0x3E, 0x90, 0x9F, 0xE1, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0x6F, 0xD8, 0x80, -0x68, 0x90, 0x9F, 0xD2, 0x12, 0x6E, 0xBB, 0x30, 0xE0, 0x1E, 0xEF, 0x54, 0xFB, 0xF0, 0xE4, 0xA3, -0xF0, 0x90, 0x9F, 0xF0, 0xE0, 0x30, 0xE0, 0x0D, 0x91, 0x65, 0xE4, 0x90, 0x9F, 0xE0, 0xF0, 0x90, -0xA1, 0xED, 0x04, 0x80, 0x0B, 0x02, 0x6F, 0xD8, 0x12, 0x4C, 0x7D, 0x90, 0x9F, 0xE1, 0xE0, 0x04, -0xF0, 0x80, 0x3C, 0x90, 0x9F, 0xD3, 0xE0, 0x64, 0x09, 0x70, 0x49, 0x90, 0x9F, 0xD2, 0xE0, 0x30, -0xE0, 0x0B, 0x12, 0x6F, 0xD8, 0x90, 0x9F, 0xD2, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x06, 0x92, -0xE0, 0x30, 0xE2, 0x1F, 0x74, 0x04, 0xF0, 0x91, 0x72, 0xE0, 0xB4, 0x02, 0x12, 0x91, 0xA1, 0x60, -0x05, 0x74, 0x05, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0xE4, 0x90, 0x9F, 0xD3, 0xF0, 0x22, 0x7F, -0x03, 0x41, 0x9C, 0x91, 0xA1, 0x60, 0x05, 0x74, 0x05, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0xE4, -0x90, 0x9F, 0xD3, 0xF0, 0x22, 0x90, 0x9F, 0xD3, 0x74, 0x09, 0xF0, 0x90, 0x06, 0x92, 0x74, 0x04, -0xF0, 0x22, 0x90, 0x9F, 0xE0, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x9F, 0xE1, 0xE0, 0xFF, 0x90, 0x9F, -0xE0, 0xE0, 0x2F, 0xFF, 0xE4, 0x33, 0xFE, 0x7C, 0x00, 0x7D, 0x03, 0x12, 0x07, 0x03, 0x90, 0x9F, -0xD7, 0xE0, 0x2F, 0xFF, 0xEC, 0x3E, 0xFE, 0xC3, 0xEF, 0x94, 0x41, 0xEE, 0x64, 0x80, 0x94, 0x80, -0x22, 0x90, 0xA1, 0xED, 0xE0, 0x90, 0x9F, 0xDE, 0x22, 0xF0, 0x90, 0x9F, 0xCD, 0xE0, 0xC4, 0x54, -0x0F, 0x22, 0x90, 0xA1, 0x18, 0xEF, 0xF0, 0x7F, 0x03, 0x51, 0x9C, 0x91, 0xAA, 0x90, 0x9F, 0xDE, -0x30, 0xE0, 0x05, 0x74, 0x05, 0xF0, 0x80, 0x03, 0xE0, 0x04, 0xF0, 0x90, 0x9F, 0xCE, 0xD1, 0x27, -0x20, 0xE0, 0x05, 0xF1, 0xBA, 0x30, 0xE0, 0x37, 0x91, 0xAA, 0x30, 0xE0, 0x0A, 0x90, 0x9F, 0xCB, -0xE0, 0xFF, 0x90, 0x9F, 0xDC, 0x80, 0x21, 0x90, 0xA1, 0x18, 0xE0, 0xFC, 0xB4, 0x01, 0x0D, 0x90, -0x9F, 0xCB, 0xE0, 0xFE, 0x90, 0x9F, 0xDB, 0xE0, 0xC3, 0x9E, 0x80, 0x0F, 0xEC, 0xB4, 0x04, 0x0F, -0x90, 0x9F, 0xCC, 0xE0, 0xFF, 0x90, 0x9F, 0xDB, 0xE0, 0xC3, 0x9F, 0x90, 0x9F, 0xE2, 0xF0, 0xD1, -0x1B, 0x30, 0xE0, 0x20, 0xF1, 0xCF, 0x20, 0xE0, 0x02, 0xA1, 0x9B, 0xB1, 0xC4, 0x50, 0x0A, 0xEF, -0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xE4, 0xFD, 0x80, 0x05, 0x7B, 0x7F, 0x7D, 0xFF, 0xE4, 0xFF, 0x12, -0x4E, 0xDE, 0x80, 0x67, 0xD1, 0x13, 0x30, 0xE0, 0x49, 0x12, 0xAA, 0x26, 0xFD, 0x7F, 0x04, 0x12, -0x5A, 0xA8, 0x12, 0x4F, 0xCF, 0x30, 0xE0, 0x3A, 0x90, 0x9F, 0xD2, 0xE0, 0x44, 0x02, 0xF0, 0x54, -0xFB, 0xF0, 0xE4, 0x90, 0x9F, 0xE1, 0xF0, 0x90, 0x9F, 0xDE, 0xF0, 0x90, 0xA1, 0x18, 0xE0, 0xFF, -0xB4, 0x01, 0x08, 0x90, 0x9F, 0xD3, 0x74, 0x06, 0xF0, 0x80, 0x0A, 0xEF, 0xB4, 0x04, 0x06, 0x90, -0x9F, 0xD3, 0x74, 0x07, 0xF0, 0x90, 0x9F, 0xBC, 0xE0, 0x60, 0x07, 0x90, 0x9F, 0xD2, 0xE0, 0x44, -0x04, 0xF0, 0x90, 0xA1, 0x18, 0xE0, 0xB4, 0x01, 0x04, 0x7D, 0x06, 0x80, 0x09, 0x90, 0xA1, 0x18, -0xE0, 0xB4, 0x04, 0x07, 0x7D, 0x0C, 0x7F, 0x6F, 0x12, 0x49, 0x1D, 0x90, 0x9F, 0xCE, 0x12, 0x66, -0xE8, 0x30, 0xE0, 0x15, 0xB1, 0xC4, 0x50, 0x0A, 0xEF, 0x7F, 0x00, 0x25, 0xE0, 0x25, 0xE0, 0xFE, -0x80, 0x04, 0x7F, 0xFF, 0x7E, 0x7F, 0x12, 0x4E, 0x11, 0x90, 0x9F, 0xCD, 0xE0, 0x30, 0xE0, 0x03, -0x12, 0x5C, 0x9B, 0x22, 0x90, 0x9F, 0xE2, 0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x22, 0xE4, 0x90, 0x9F, -0xD3, 0xF0, 0x90, 0x9F, 0xDE, 0x22, 0x90, 0x9F, 0xCA, 0xE0, 0x30, 0xE0, 0x35, 0x51, 0xB9, 0x90, -0x9F, 0xDE, 0xE0, 0xFF, 0xB4, 0x01, 0x02, 0x80, 0x1C, 0x90, 0x9F, 0xDE, 0xE0, 0xFF, 0xB4, 0x02, -0x02, 0x80, 0x1C, 0x90, 0x9F, 0xDE, 0xE0, 0xFF, 0xB4, 0x03, 0x02, 0x01, 0xD0, 0x90, 0x9F, 0xDE, -0xE0, 0xFF, 0xB4, 0x04, 0x02, 0x81, 0xB2, 0x90, 0x9F, 0xDE, 0xE0, 0xFF, 0xB4, 0x05, 0x03, 0x12, -0x65, 0x60, 0x22, 0x90, 0x9F, 0xCA, 0xE0, 0xC4, 0x54, 0x0F, 0x22, 0x90, 0x9F, 0xCA, 0xE0, 0xC4, -0x13, 0x54, 0x07, 0x22, 0x90, 0x9F, 0xCA, 0xE0, 0xFF, 0xC4, 0x13, 0x54, 0x07, 0x22, 0xE4, 0xFF, -0x90, 0x9F, 0xCA, 0xE0, 0x30, 0xE0, 0x2C, 0xA3, 0x51, 0x98, 0x90, 0x9F, 0xDE, 0x74, 0x01, 0xF0, -0x90, 0x9F, 0xDD, 0xF0, 0x90, 0x9F, 0xBC, 0xE0, 0x60, 0x07, 0x7D, 0x05, 0x7F, 0x6F, 0x02, 0x49, -0x1D, 0x12, 0x5C, 0x9B, 0xD1, 0x24, 0x20, 0xE0, 0x0A, 0xEF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, -0x02, 0xF1, 0xD8, 0x22, 0xD1, 0xBB, 0x7F, 0x04, 0x8F, 0x71, 0x7F, 0x02, 0x12, 0x44, 0xB7, 0x90, -0x9D, 0x93, 0xE0, 0x45, 0x71, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, -0xB9, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0x12, 0x45, 0xBE, 0x12, 0xA8, 0xFA, 0x70, 0x21, 0x90, -0xFD, 0x58, 0xE0, 0x20, 0xE0, 0x12, 0x90, 0xA1, 0xB9, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0x12, -0x45, 0xB5, 0xD1, 0xE1, 0x7F, 0x01, 0x80, 0x0E, 0x7F, 0x01, 0xD1, 0x64, 0x7F, 0x02, 0x80, 0x06, -0x7F, 0x02, 0xD1, 0x64, 0x7F, 0x03, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, -0xC0, 0xD0, 0x90, 0xA1, 0x8E, 0x74, 0x15, 0xF0, 0x90, 0xA1, 0x9C, 0x74, 0x01, 0xF0, 0x90, 0xA1, -0x90, 0xEF, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x8E, 0x12, 0x8A, 0xE4, 0xD0, 0xD0, 0x92, 0xAF, -0x22, 0x90, 0xA1, 0xEF, 0x12, 0x45, 0xBE, 0xE4, 0xFE, 0x90, 0xFD, 0x50, 0xEF, 0xF0, 0x64, 0x30, -0x60, 0x1E, 0xA3, 0xED, 0xF0, 0xEE, 0xC3, 0x9D, 0x50, 0x09, 0xF1, 0x33, 0xF1, 0x28, 0xEF, 0xF0, -0x0E, 0x80, 0xF2, 0xEE, 0xC3, 0x94, 0x06, 0x50, 0x18, 0xF1, 0x28, 0xE4, 0xF0, 0x0E, 0x80, 0xF3, -0xEE, 0xC3, 0x94, 0x07, 0x50, 0x0B, 0xF1, 0x33, 0x74, 0x51, 0xF1, 0x2A, 0xEF, 0xF0, 0x0E, 0x80, -0xEF, 0x90, 0xFD, 0x58, 0x74, 0x01, 0xF0, 0x22, 0x74, 0x52, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFD, -0xF5, 0x83, 0x22, 0x90, 0xA1, 0xEF, 0x12, 0x45, 0xB5, 0x8E, 0x82, 0x75, 0x83, 0x00, 0x12, 0x06, -0xA2, 0xFF, 0x22, 0x90, 0x9F, 0x0E, 0xE0, 0x30, 0xE0, 0x10, 0xA3, 0x74, 0x01, 0xF0, 0x90, 0x9F, -0x0E, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, 0x02, 0xF1, 0x5F, 0x12, 0x90, 0x6F, 0x01, 0xC4, 0xD3, -0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x9F, 0x0D, 0xE0, 0xB4, 0x01, 0x04, 0x7F, 0x04, 0x80, -0x0C, 0x12, 0x6E, 0x19, 0xBF, 0x01, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x12, 0x99, 0x15, -0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0x16, 0xF1, 0xAB, 0xB4, 0x02, -0x19, 0x90, 0xA1, 0xEC, 0xE0, 0x64, 0x04, 0x60, 0x0C, 0x7F, 0x40, 0x12, 0x8B, 0xCF, 0x90, 0xA1, -0xEC, 0xE0, 0x04, 0xF0, 0x22, 0xE4, 0x90, 0xA1, 0xEC, 0xF0, 0x22, 0x7D, 0x03, 0x7F, 0x11, 0xD1, -0x77, 0xEF, 0x22, 0x22, 0x7D, 0x01, 0x7F, 0x17, 0xC1, 0x77, 0xEF, 0x13, 0x13, 0x13, 0x54, 0x1F, -0x22, 0x7D, 0x02, 0x7F, 0x02, 0x02, 0x5E, 0xB8, 0x12, 0x8A, 0x5E, 0x7F, 0x04, 0xC1, 0x68, 0x90, -0x9F, 0xCE, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x22, 0x90, 0x9F, 0xBB, 0xE0, 0xC4, 0x54, 0x0F, 0x20, -0xE0, 0x1D, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x17, 0x90, 0x9D, 0x9A, 0xE0, 0xFF, 0x7B, 0x18, 0xE4, -0xFD, 0x12, 0x4D, 0x56, 0x90, 0xA2, 0x0A, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x4F, 0x0A, 0x22, -0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, -0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, -0x74, 0x00, 0xF0, 0x74, 0x88, 0xA3, 0xF0, 0x11, 0x52, 0x53, 0x91, 0xBF, 0x74, 0x00, 0x04, 0x90, -0x01, 0xC4, 0xF0, 0x74, 0x88, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, -0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, -0xE0, 0x32, 0x90, 0xFD, 0x68, 0xE0, 0xFF, 0x90, 0xFD, 0x60, 0xE0, 0x90, 0xA1, 0x27, 0xF0, 0xEF, -0x20, 0xE0, 0x02, 0x41, 0x2D, 0x90, 0xA1, 0xEE, 0xE0, 0x70, 0x1A, 0x7F, 0x2E, 0x12, 0x47, 0xBF, -0x90, 0xA0, 0x08, 0xEF, 0xF0, 0x7F, 0x2D, 0x12, 0x47, 0xBF, 0x90, 0xA0, 0x09, 0xEF, 0xF0, 0x90, -0xA1, 0xEE, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0x27, 0xE0, 0x64, 0x15, 0x70, 0x58, 0x90, 0xFD, 0x62, -0xE0, 0xFF, 0x30, 0xE6, 0x11, 0xF4, 0x54, 0x3F, 0x04, 0xFE, 0x51, 0x3D, 0xC3, 0x9E, 0x51, 0x35, -0x40, 0x12, 0xE4, 0xF0, 0x80, 0x0E, 0x51, 0x3D, 0xFE, 0xEF, 0x54, 0x3F, 0x2E, 0x51, 0x35, 0x40, -0x03, 0x74, 0x3F, 0xF0, 0x90, 0xA1, 0x26, 0xE0, 0xFF, 0x54, 0x30, 0xC4, 0x54, 0x0F, 0xFE, 0xEF, -0x25, 0xE0, 0x25, 0xE0, 0x4E, 0x90, 0xA1, 0x24, 0xF0, 0xE0, 0xFD, 0x7F, 0x2E, 0x12, 0x46, 0xA0, -0x90, 0xA1, 0x26, 0xE0, 0xC4, 0x54, 0xF0, 0xFF, 0x90, 0xA0, 0x09, 0xE0, 0x54, 0x0F, 0x4F, 0xFD, -0x7F, 0x2D, 0x12, 0x46, 0xA0, 0x90, 0xA1, 0x27, 0xE0, 0xB4, 0x21, 0x0C, 0x90, 0xFD, 0x62, 0xE0, -0xFF, 0x71, 0x98, 0x7F, 0x04, 0x12, 0x86, 0x68, 0x90, 0xA1, 0x27, 0xE0, 0xB4, 0x23, 0x05, 0x7F, -0x01, 0x12, 0x87, 0xC8, 0x90, 0xA1, 0x27, 0xE0, 0xB4, 0x27, 0x05, 0x7F, 0x02, 0x12, 0x87, 0xC8, -0x90, 0xA1, 0x27, 0xE0, 0xB4, 0x30, 0x0C, 0xE4, 0xFB, 0xFD, 0x7F, 0x01, 0xB1, 0x83, 0x7F, 0x04, -0x12, 0x86, 0x68, 0x90, 0xA1, 0x27, 0xE0, 0x64, 0x34, 0x60, 0x02, 0x21, 0xCB, 0x90, 0xFD, 0x62, -0xE0, 0x30, 0xE0, 0x5B, 0x90, 0x9F, 0xF0, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, 0x02, 0x21, 0xCB, -0x90, 0x9F, 0xCD, 0x12, 0x4F, 0xD2, 0x30, 0xE0, 0x1A, 0x51, 0x2E, 0x90, 0x9F, 0xF1, 0xEE, 0xF0, -0xA3, 0xEF, 0xF0, 0x51, 0x2E, 0xE4, 0xFF, 0xFE, 0xEC, 0x12, 0x47, 0xE1, 0x7F, 0x48, 0x7E, 0x09, -0x12, 0x38, 0x45, 0x51, 0x46, 0x7D, 0x01, 0x12, 0x46, 0xB5, 0x90, 0xA1, 0x24, 0x74, 0x01, 0xF0, -0xFB, 0x7A, 0xA1, 0x79, 0x24, 0xFD, 0x7F, 0x34, 0x12, 0x86, 0x77, 0x90, 0xA0, 0x13, 0xE0, 0x44, -0x01, 0xF0, 0x90, 0x04, 0x9D, 0xE4, 0xF0, 0xE0, 0x44, 0x01, 0xF0, 0x71, 0x41, 0x80, 0x3C, 0x51, -0x46, 0xE4, 0xFD, 0x12, 0x46, 0xB5, 0x90, 0x9F, 0xCD, 0x12, 0x69, 0xCD, 0x30, 0xE0, 0x21, 0x51, -0x2E, 0xE4, 0xFB, 0xFA, 0xED, 0xF9, 0xEC, 0xF8, 0x90, 0x9F, 0xF1, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, -0xE4, 0xFC, 0xFD, 0x12, 0x45, 0x53, 0x12, 0x47, 0xE1, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, -0xF1, 0xA9, 0x90, 0x04, 0x9D, 0xE0, 0x54, 0xFE, 0xF0, 0x71, 0x90, 0x90, 0xA1, 0x27, 0xE0, 0xFD, -0xB4, 0x35, 0x07, 0x90, 0x9F, 0xD2, 0xE0, 0x44, 0x01, 0xF0, 0xED, 0xB4, 0x36, 0x23, 0x90, 0xFD, -0x61, 0xE0, 0x90, 0xA1, 0x24, 0xF0, 0x90, 0xFD, 0x62, 0xE0, 0x90, 0xA1, 0x25, 0xF0, 0x90, 0xA1, -0x27, 0xE0, 0xFF, 0x90, 0xA1, 0x24, 0xE0, 0xFD, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x25, 0x12, 0x86, -0x77, 0x90, 0xA1, 0x27, 0xE0, 0xB4, 0x37, 0x03, 0x12, 0x98, 0x3A, 0x90, 0xA1, 0x27, 0xE0, 0xB4, -0x40, 0x14, 0x90, 0xFD, 0x62, 0xE0, 0x30, 0xE0, 0x08, 0x90, 0x9F, 0xEE, 0x74, 0x01, 0xF0, 0x80, -0x05, 0xE4, 0x90, 0x9F, 0xEE, 0xF0, 0x90, 0xFD, 0x68, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x7F, 0x48, -0x7E, 0x09, 0x02, 0x37, 0x4E, 0x90, 0xA1, 0x26, 0xF0, 0xD3, 0x94, 0x3F, 0x22, 0x90, 0xA0, 0x08, -0xE0, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x90, 0x9F, 0xCD, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x01, 0xFF, -0x90, 0xA0, 0x0D, 0xE0, 0xFB, 0x90, 0xA0, 0x0C, 0xE0, 0x90, 0xA1, 0xCF, 0xF0, 0x22, 0x90, 0xA1, -0x70, 0x74, 0x09, 0xF0, 0x90, 0xA1, 0x7E, 0x74, 0x07, 0xF0, 0x90, 0xA1, 0x72, 0xEF, 0xF0, 0x70, -0x31, 0x90, 0x9F, 0xE4, 0xE0, 0x60, 0x1A, 0xA3, 0xE0, 0x60, 0x02, 0x80, 0x0C, 0x90, 0x07, 0x70, -0xE0, 0x70, 0x06, 0x90, 0x07, 0x74, 0xE0, 0x60, 0x08, 0x90, 0xA1, 0x73, 0x74, 0x01, 0xF0, 0x80, -0x05, 0xE4, 0x90, 0xA1, 0x73, 0xF0, 0xE4, 0x90, 0xA1, 0x74, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, -0x80, 0x39, 0x90, 0xFD, 0x62, 0xE0, 0x90, 0xA1, 0x73, 0xF0, 0x90, 0xFD, 0x63, 0xE0, 0x90, 0xA1, -0x74, 0xF0, 0x90, 0xFD, 0x64, 0xE0, 0x90, 0xA1, 0x75, 0xF0, 0x90, 0xFD, 0x65, 0xE0, 0x90, 0xA1, -0x76, 0xF0, 0x90, 0xFD, 0x66, 0xE0, 0x90, 0xA1, 0x77, 0xF0, 0x90, 0xFD, 0x67, 0xE0, 0x90, 0xA1, -0x78, 0xF0, 0x90, 0xA1, 0x73, 0xE0, 0x54, 0x01, 0x90, 0x9F, 0xE4, 0xF0, 0xA3, 0xF0, 0x7B, 0x01, -0x7A, 0xA1, 0x79, 0x70, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x9E, 0x88, 0xE0, 0xFF, -0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x9E, 0x89, 0xE0, 0xB5, -0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, -0x02, 0xF0, 0x80, 0x28, 0xC0, 0x01, 0x90, 0x9E, 0x89, 0xE0, 0xF1, 0xB4, 0xA8, 0x01, 0xFC, 0x7D, -0x01, 0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x06, 0x63, 0x90, 0x9E, 0x89, 0xF1, 0x7B, 0xB4, -0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x9E, 0x89, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, -0x22, 0x90, 0x01, 0xE7, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x54, 0x01, 0xF1, 0x98, -0x54, 0xFD, 0x4F, 0xF0, 0xE0, 0xC3, 0x13, 0xFF, 0x54, 0x01, 0x90, 0x01, 0xE6, 0xF0, 0xA3, 0xE0, -0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE0, 0x27, 0x12, 0xA8, 0xFA, 0x70, 0x20, 0x90, 0xA0, 0x13, 0xE0, -0x30, 0xE0, 0x02, 0x80, 0x19, 0x90, 0xFD, 0x62, 0xE0, 0xB4, 0xAD, 0x0E, 0xA3, 0xE0, 0xB4, 0x35, -0x09, 0x71, 0x41, 0x90, 0x01, 0xE5, 0x74, 0xDF, 0xF0, 0x22, 0x80, 0x00, 0x80, 0x02, 0x80, 0xB1, -0x90, 0x01, 0xE7, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0xA1, 0x28, 0x74, 0x08, 0xF0, 0x90, 0xA1, -0x36, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0x2A, 0xEF, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x28, 0x41, -0xE4, 0x90, 0x9F, 0xF3, 0xE0, 0x44, 0x04, 0xF0, 0x7D, 0x01, 0x7F, 0x23, 0x12, 0x86, 0x77, 0x8F, -0x51, 0xE5, 0x51, 0xB4, 0x03, 0x08, 0xE4, 0xFF, 0x51, 0x5E, 0x7F, 0x04, 0x71, 0xCF, 0x22, 0x90, -0xA2, 0x0D, 0xF1, 0x89, 0x90, 0x9D, 0x93, 0xE0, 0xFF, 0x90, 0xA2, 0x0D, 0xE0, 0xFE, 0xEF, 0x4E, -0x90, 0x9D, 0x93, 0xF0, 0x22, 0x90, 0xA1, 0x39, 0xEB, 0xF0, 0x70, 0x5C, 0x90, 0xA1, 0x39, 0xE0, -0xFE, 0x91, 0x49, 0xE0, 0xFC, 0x90, 0xA1, 0x3A, 0xE0, 0xFB, 0xEC, 0x6B, 0x60, 0x4A, 0x90, 0xA1, -0x3E, 0xEB, 0xF0, 0xA3, 0xEE, 0xF0, 0xAE, 0x05, 0xEE, 0x25, 0xE0, 0x4F, 0xFF, 0x90, 0x9D, 0x92, -0xE0, 0xFE, 0x25, 0xE0, 0x25, 0xE0, 0x4F, 0x90, 0xA1, 0x40, 0xF0, 0x90, 0xA1, 0x3B, 0xE0, 0x90, -0xA1, 0x42, 0xF0, 0x90, 0xA1, 0x3C, 0x74, 0x0C, 0xF0, 0x90, 0xA1, 0x4A, 0x74, 0x04, 0xF0, 0x7B, -0x01, 0x7A, 0xA1, 0x79, 0x3C, 0x51, 0xE4, 0x7F, 0x04, 0x71, 0xCF, 0x90, 0xA1, 0x3A, 0xE0, 0xFF, -0x90, 0xA1, 0x39, 0xE0, 0x91, 0x49, 0xEF, 0xF0, 0x22, 0x24, 0x92, 0xF5, 0x82, 0xE4, 0x34, 0x98, -0xF5, 0x83, 0x22, 0x90, 0xA0, 0xF9, 0x74, 0x12, 0xF0, 0x90, 0xA1, 0x07, 0x74, 0x05, 0xF0, 0x90, -0xA0, 0xFB, 0xEF, 0x12, 0x4F, 0xBE, 0x90, 0xA0, 0xF7, 0xE0, 0x90, 0xA0, 0xFE, 0xF0, 0x90, 0xA0, -0xF8, 0xE0, 0x90, 0xA0, 0xFF, 0xF0, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0xF9, 0x51, 0xE4, 0x7F, 0x04, -0x61, 0xCF, 0x91, 0xFF, 0x7F, 0xF5, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x06, 0x90, 0xA0, -0xEE, 0xE0, 0xA3, 0xF0, 0x91, 0xFF, 0x7F, 0xF6, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, -0x90, 0xA0, 0xEE, 0xE0, 0x90, 0xA0, 0xF0, 0xF0, 0x91, 0xFF, 0x7F, 0xF4, 0x7E, 0x01, 0x12, 0x34, -0xC1, 0xBF, 0x01, 0x08, 0x90, 0xA0, 0xEE, 0xE0, 0x90, 0xA0, 0xF1, 0xF0, 0x91, 0xFF, 0x7F, 0xF3, -0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0xA0, 0xEE, 0xE0, 0x90, 0xA0, 0xF2, 0xF0, -0x91, 0xFF, 0x7F, 0xF2, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0xA0, 0xEE, 0xE0, -0x90, 0xA0, 0xF3, 0xF0, 0x90, 0xA0, 0xEF, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, -0xE0, 0x90, 0xA0, 0xF7, 0xF0, 0x90, 0xA0, 0xF3, 0xE0, 0x90, 0xA0, 0xF8, 0xF0, 0x81, 0x53, 0x7B, -0x01, 0x7A, 0xA0, 0x79, 0xEE, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x06, 0x89, -0x90, 0xA0, 0xEE, 0x12, 0x57, 0xC4, 0x90, 0xA0, 0xEF, 0x12, 0x56, 0xBB, 0x90, 0xA0, 0xF0, 0xF0, -0x12, 0x56, 0xE7, 0x90, 0xA0, 0xF1, 0x12, 0x6C, 0xDD, 0x90, 0xA0, 0xF2, 0xD1, 0xC3, 0x90, 0x9F, -0xF3, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0xA0, 0xEF, 0xE0, 0xB4, 0x0C, 0x06, 0xE5, 0x70, 0x70, 0x0D, -0x80, 0x00, 0x91, 0xFF, 0x7D, 0x07, 0x7F, 0x30, 0x12, 0x86, 0x77, 0x8F, 0x51, 0x90, 0xA0, 0xEF, -0xE0, 0xB4, 0x0D, 0x0E, 0xE5, 0x51, 0x64, 0x01, 0x60, 0x05, 0x75, 0x70, 0x01, 0x80, 0x03, 0xE4, -0xF5, 0x70, 0xE5, 0x51, 0xB4, 0x01, 0x05, 0x75, 0x52, 0x01, 0x80, 0x03, 0xE4, 0xF5, 0x52, 0x90, -0xA0, 0xEE, 0xE0, 0xFB, 0xAD, 0x52, 0xE4, 0xFF, 0xB1, 0x83, 0x7F, 0x04, 0x71, 0xCF, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0x90, 0xA1, 0x7F, 0x74, 0x0B, 0xF0, 0x90, 0xA1, 0x8D, 0x74, 0x07, 0xF0, 0x90, -0xA1, 0x81, 0xEF, 0xF0, 0x60, 0x32, 0x90, 0xFD, 0x63, 0xE0, 0x90, 0xA1, 0x82, 0xF0, 0x90, 0xFD, -0x61, 0xE0, 0x90, 0xA1, 0x83, 0xF0, 0x90, 0xFD, 0x64, 0xE0, 0x90, 0xA1, 0x84, 0xF0, 0x90, 0xFD, -0x65, 0xE0, 0x90, 0xA1, 0x85, 0xF0, 0x90, 0xFD, 0x66, 0xE0, 0x90, 0xA1, 0x86, 0xF0, 0x90, 0xFD, -0x67, 0xE0, 0x90, 0xA1, 0x87, 0xF0, 0x80, 0x0D, 0x90, 0xA1, 0x82, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, -0xE4, 0xA3, 0x12, 0x58, 0xB2, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x7F, 0x41, 0xE4, 0x12, 0xA2, 0x59, -0x7F, 0x08, 0x12, 0x47, 0xBF, 0xEF, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x46, 0xA0, 0xE4, 0xFF, -0xD1, 0x76, 0x51, 0x46, 0xE4, 0xFD, 0x12, 0x46, 0xB5, 0x90, 0x9F, 0x13, 0xE0, 0xFF, 0xC4, 0x54, -0x0F, 0x30, 0xE0, 0x03, 0x12, 0xA7, 0x8C, 0x90, 0x9F, 0x14, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0xD3, -0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xD1, 0x1F, 0xB1, 0xDD, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, -0x9F, 0x14, 0xE0, 0x44, 0x10, 0xF0, 0x51, 0x46, 0x7D, 0x01, 0x12, 0x46, 0xB5, 0x90, 0x9F, 0x21, -0xE0, 0xFD, 0x7F, 0x93, 0x12, 0x46, 0xA0, 0x90, 0x9F, 0x18, 0xE0, 0x60, 0x12, 0x90, 0x01, 0x2F, -0xE0, 0x30, 0xE7, 0x05, 0x74, 0x10, 0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0, 0x7F, -0x08, 0x12, 0x47, 0xBF, 0xEF, 0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, 0x46, 0xA0, 0x7F, 0x01, 0xD1, -0x76, 0x7F, 0x90, 0x12, 0x47, 0xBF, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12, 0x46, 0xA0, 0x7F, -0x14, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x90, 0xA1, 0xFB, 0xD1, 0xC2, 0x90, 0x01, 0x09, 0xE0, 0x7F, -0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x90, 0xA1, 0xFB, 0xE0, 0x6F, 0x60, 0x34, 0xC3, 0x90, 0xA1, -0xFD, 0xE0, 0x94, 0x88, 0x90, 0xA1, 0xFC, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, -0x44, 0x10, 0xF0, 0x22, 0x90, 0xA1, 0xFC, 0xF1, 0x74, 0xF1, 0x82, 0xD3, 0x90, 0xA1, 0xFD, 0xE0, -0x94, 0x32, 0x90, 0xA1, 0xFC, 0xE0, 0x94, 0x00, 0x40, 0xC1, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0, -0xBA, 0x22, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x9F, 0x1A, 0xE0, 0xFF, 0x60, -0x03, 0xB4, 0x08, 0x08, 0x12, 0xA7, 0x63, 0xBF, 0x01, 0x02, 0xD1, 0x0F, 0x22, 0x90, 0x9F, 0x13, -0xE0, 0x30, 0xE0, 0x18, 0x90, 0x9F, 0x0E, 0xE0, 0xFF, 0x30, 0xE0, 0x0E, 0xC3, 0x13, 0x30, 0xE0, -0x07, 0xF1, 0xC0, 0xBF, 0x01, 0x06, 0x80, 0x02, 0x80, 0x00, 0xD1, 0xCA, 0x22, 0x90, 0xA0, 0xEE, -0x74, 0x0A, 0xF0, 0x90, 0xA0, 0xFC, 0x74, 0x06, 0xF0, 0x12, 0x06, 0x89, 0x90, 0xA0, 0xF0, 0x12, -0x57, 0xC4, 0x90, 0xA0, 0xF1, 0x12, 0x56, 0xBB, 0x90, 0xA0, 0xF2, 0xF0, 0x12, 0x56, 0xE7, 0x90, -0xA0, 0xF3, 0x12, 0x6C, 0xDD, 0x90, 0xA0, 0xF4, 0x12, 0x5E, 0x3A, 0x90, 0xA0, 0xF5, 0xF0, 0x91, -0xFF, 0x41, 0xE4, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xD0, 0xEE, 0xF0, 0xA3, -0xD1, 0xC2, 0x90, 0xA1, 0xD0, 0xF1, 0xA0, 0xE0, 0x60, 0x23, 0xC3, 0x90, 0xA1, 0xD3, 0xE0, 0x94, -0xE8, 0x90, 0xA1, 0xD2, 0xE0, 0x94, 0x03, 0x40, 0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0, -0x7F, 0x00, 0x80, 0x0B, 0x90, 0xA1, 0xD2, 0xF1, 0x74, 0xF1, 0x91, 0x80, 0xD5, 0x7F, 0x01, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x08, 0xD6, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, -0x00, 0x22, 0x7F, 0x14, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0xEF, 0xF0, 0x7F, 0x02, 0x02, 0x44, 0xB7, -0xF0, 0x7F, 0x0A, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x25, 0xE0, 0xFF, 0x90, 0x9F, 0xF0, 0xE0, 0x22, -0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0x22, 0x90, 0xA0, 0x13, 0xE0, 0x54, 0xFE, 0xF0, -0xE4, 0xA3, 0xF0, 0x22, 0x75, 0xF0, 0x0F, 0xA4, 0x24, 0xF2, 0xF9, 0x74, 0x9D, 0x35, 0xF0, 0x22, -0x90, 0x9F, 0x11, 0xE0, 0x64, 0x02, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x90, 0x9F, 0xFD, -0xE0, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x16, 0xEF, 0xB4, 0x01, 0x05, 0x90, 0xA0, 0x04, 0x80, 0x03, -0x90, 0xA0, 0x00, 0x12, 0x47, 0xDF, 0x7F, 0x80, 0x7E, 0x08, 0x12, 0x38, 0x45, 0x22, 0x12, 0x97, -0x07, 0x30, 0xE0, 0x1E, 0x12, 0x87, 0xBA, 0x20, 0xE0, 0x18, 0x12, 0x84, 0xAA, 0x30, 0xE0, 0x04, -0x7F, 0x03, 0x80, 0x0B, 0xF1, 0x40, 0x30, 0xE0, 0x04, 0x7F, 0x0D, 0x80, 0x02, 0x7F, 0x09, 0x12, -0x62, 0x14, 0x22, 0xE4, 0x90, 0xA1, 0x18, 0xF0, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x50, 0x31, 0x23, -0x70, 0x4C, 0x90, 0xA1, 0x18, 0x04, 0xF0, 0xE4, 0x90, 0x9F, 0x1E, 0xF0, 0x90, 0x9F, 0x0E, 0xE0, -0x30, 0xE0, 0x16, 0x90, 0x9F, 0x12, 0xE0, 0xB4, 0x02, 0x05, 0xE4, 0x90, 0xA1, 0x18, 0xF0, 0x12, -0x6E, 0x19, 0xEF, 0x70, 0x04, 0x90, 0xA1, 0x18, 0xF0, 0x90, 0xA1, 0x18, 0xE0, 0x60, 0x1F, 0x90, -0x9F, 0x1B, 0xE0, 0x44, 0x10, 0x71, 0xC3, 0x90, 0x9F, 0x1F, 0xE0, 0x90, 0xA1, 0xB2, 0x12, 0x48, -0x27, 0x90, 0x9F, 0x1A, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x5A, 0xA4, 0x12, 0x8F, 0xEE, 0x22, 0xE4, -0xF5, 0x63, 0x90, 0x9F, 0x17, 0xE0, 0x70, 0x02, 0x21, 0x18, 0x31, 0x23, 0x60, 0x02, 0x21, 0x18, -0x90, 0x9F, 0x13, 0xE0, 0x30, 0xE0, 0x16, 0x91, 0x93, 0xFD, 0xED, 0x78, 0x02, 0xCE, 0xC3, 0x13, -0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0x9F, 0x4C, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x31, 0x2A, 0x60, -0x22, 0x24, 0xFE, 0x60, 0x03, 0x04, 0x70, 0x1E, 0x90, 0x9F, 0x1E, 0xE0, 0x14, 0xF0, 0xE0, 0xFF, -0x60, 0x06, 0x90, 0x9F, 0x20, 0xE0, 0x60, 0x0E, 0xEF, 0x70, 0x08, 0x90, 0x9F, 0x1D, 0xE0, 0xA3, -0xF0, 0x80, 0x00, 0x75, 0x63, 0x01, 0x90, 0x9F, 0x0E, 0xE0, 0x30, 0xE0, 0x12, 0x90, 0x9F, 0x12, -0xE0, 0xB4, 0x02, 0x03, 0xE4, 0xF5, 0x63, 0x12, 0x6E, 0x19, 0xEF, 0x70, 0x02, 0xF5, 0x63, 0xE5, -0x63, 0x60, 0x35, 0x90, 0x9F, 0x1B, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x9F, 0x20, 0xE0, 0x60, 0x03, -0xB4, 0x01, 0x04, 0x31, 0x19, 0x80, 0x08, 0x31, 0x19, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, -0x90, 0x9F, 0x1F, 0xE0, 0x2F, 0x90, 0xA1, 0xB2, 0x12, 0x48, 0x27, 0x90, 0x9F, 0x1A, 0xE0, 0x20, -0xE2, 0x03, 0x12, 0x5A, 0xA4, 0x12, 0x8F, 0xEE, 0x22, 0xE4, 0x90, 0xA1, 0xB1, 0xF0, 0x90, 0x9F, -0x20, 0xE0, 0x22, 0x90, 0x9E, 0x8D, 0xE0, 0x64, 0x01, 0x22, 0x90, 0x9F, 0x15, 0xE0, 0xFF, 0xC4, -0x54, 0x0F, 0x22, 0x31, 0x23, 0x70, 0x73, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x6D, 0x31, 0x2A, 0x64, -0x01, 0x70, 0x26, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x9F, 0x1E, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x04, -0x90, 0x9F, 0x1D, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x9F, 0x1D, 0xE0, 0xFE, 0xFF, 0x80, -0x03, 0xEF, 0x04, 0xFF, 0x90, 0x9F, 0x1E, 0xEF, 0xF0, 0x90, 0x9F, 0x13, 0xE0, 0x30, 0xE0, 0x02, -0x71, 0xCA, 0x31, 0xB6, 0xE4, 0x90, 0x9F, 0x20, 0xB1, 0x37, 0x31, 0xD0, 0x31, 0xFA, 0x54, 0xEF, -0xF0, 0x31, 0x2A, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x0D, 0x90, 0x9F, 0x0E, 0xE0, 0x30, 0xE0, 0x04, -0x51, 0xEE, 0x80, 0x02, 0x51, 0x98, 0x90, 0x9F, 0x14, 0x12, 0x66, 0xE8, 0x30, 0xE0, 0x0B, 0x51, -0x90, 0xB5, 0x07, 0x06, 0x12, 0x6F, 0x47, 0x12, 0x5F, 0x61, 0x90, 0x9F, 0x0E, 0xE0, 0xC3, 0x13, -0x20, 0xE0, 0x02, 0x31, 0xB6, 0x22, 0x90, 0x9F, 0x14, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x31, 0x23, -0x70, 0x0D, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x07, 0x31, 0xD0, 0x71, 0x66, 0x12, 0x48, 0x27, 0x22, -0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x22, 0x31, 0x23, 0x70, 0x15, -0x90, 0x9F, 0x17, 0xE0, 0x60, 0x0F, 0x31, 0xD0, 0x90, 0x9F, 0x13, 0xE0, 0x31, 0xF7, 0x54, 0x07, -0x70, 0x03, 0x12, 0x68, 0x3E, 0x22, 0xEF, 0x54, 0xFB, 0xF0, 0x90, 0x9F, 0x1B, 0xE0, 0x54, 0xFD, -0xF0, 0x22, 0x90, 0x01, 0x57, 0xE0, 0x60, 0x1A, 0x31, 0xD3, 0x90, 0x9F, 0x13, 0x12, 0x6E, 0xBB, -0x30, 0xE0, 0x02, 0x80, 0xE1, 0xB1, 0x42, 0x40, 0x09, 0x90, 0x9E, 0x8D, 0xE0, 0xB4, 0x01, 0x02, -0xF1, 0x49, 0x22, 0xEF, 0x60, 0x2D, 0x31, 0x23, 0x70, 0x29, 0x90, 0x9F, 0x14, 0xE0, 0x54, 0xFE, -0xF0, 0x7D, 0x2B, 0x7F, 0x0F, 0x12, 0x49, 0x1D, 0x90, 0x06, 0x04, 0xE0, 0x54, 0xBF, 0xF0, 0x71, -0x83, 0xBF, 0x01, 0x0F, 0x90, 0x9F, 0x13, 0xE0, 0x44, 0x40, 0xF0, 0x7D, 0x06, 0x12, 0x5F, 0x53, -0x74, 0x06, 0xF0, 0x22, 0x90, 0x9F, 0x0E, 0xE0, 0xFF, 0x30, 0xE0, 0x05, 0x12, 0x6E, 0xE5, 0x60, -0x2E, 0x90, 0x9F, 0x17, 0xE0, 0x70, 0x04, 0xEF, 0x30, 0xE0, 0x0A, 0x90, 0x9F, 0x1A, 0xE0, 0x64, -0x02, 0x60, 0x1C, 0x31, 0x33, 0x90, 0x9F, 0x14, 0x12, 0x66, 0xE8, 0x30, 0xE0, 0x11, 0x51, 0x90, -0x6F, 0x70, 0x0C, 0x12, 0x6F, 0x47, 0x12, 0x5F, 0x5B, 0x90, 0x9F, 0x1E, 0xE0, 0x14, 0xF0, 0x22, -0x90, 0x9F, 0x1D, 0xE0, 0xFF, 0xA3, 0xE0, 0x22, 0xE4, 0xF5, 0x63, 0x90, 0x06, 0xA9, 0xE0, 0xF5, -0x63, 0x54, 0xC0, 0x70, 0x08, 0x51, 0xE6, 0x54, 0xFD, 0xF0, 0x02, 0x68, 0x3E, 0xE5, 0x63, 0x30, -0xE6, 0x18, 0x90, 0x9F, 0x17, 0xE0, 0x64, 0x01, 0x70, 0x12, 0x12, 0x6F, 0x8E, 0x64, 0x02, 0x60, -0x05, 0x12, 0x87, 0xD8, 0x80, 0x06, 0x71, 0x73, 0x80, 0x02, 0x51, 0xE6, 0xE5, 0x63, 0x90, 0x9F, -0x1B, 0x30, 0xE7, 0x0D, 0x71, 0x62, 0x12, 0x48, 0x27, 0x90, 0x9F, 0x13, 0xE0, 0x44, 0x04, 0xF0, -0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x9F, 0x1B, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x06, -0xA9, 0xE0, 0x90, 0xA1, 0x08, 0xF0, 0xE0, 0xFD, 0x54, 0xC0, 0x70, 0x04, 0x51, 0xE6, 0x80, 0x5E, -0xED, 0x30, 0xE6, 0x40, 0x90, 0x9F, 0x17, 0xE0, 0x64, 0x02, 0x70, 0x28, 0x90, 0x9F, 0x13, 0xE0, -0xFF, 0xC3, 0x13, 0x20, 0xE0, 0x09, 0x90, 0x9F, 0x1B, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x1C, 0x12, -0x6F, 0x95, 0x64, 0x01, 0x70, 0x20, 0x90, 0x9F, 0x1B, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x01, 0x12, -0x4D, 0xD2, 0x80, 0x12, 0x12, 0x6F, 0x8E, 0x64, 0x02, 0x60, 0x05, 0x12, 0x87, 0xD8, 0x80, 0x06, -0x71, 0x73, 0x80, 0x02, 0x51, 0xE6, 0x90, 0xA1, 0x08, 0xE0, 0x90, 0x9F, 0x1B, 0x30, 0xE7, 0x0D, -0x71, 0x62, 0x12, 0x48, 0x27, 0x90, 0x9F, 0x13, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54, 0xFD, -0xF0, 0x22, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0x90, 0xA1, 0xB1, 0xF0, 0x90, 0x9F, 0xB7, 0xE0, 0x90, -0xA1, 0xB2, 0x22, 0x71, 0x8A, 0x90, 0x9F, 0x1A, 0xE0, 0x64, 0x0C, 0x60, 0x05, 0x12, 0x5C, 0x95, -0x71, 0x83, 0x22, 0x7D, 0x08, 0xE4, 0xFF, 0x02, 0x4C, 0x88, 0x90, 0x9F, 0x13, 0x12, 0x66, 0xE8, -0x30, 0xE0, 0x05, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0, 0x90, 0x01, -0x3C, 0x74, 0x04, 0x71, 0xC3, 0x90, 0x9F, 0xB8, 0xE0, 0xC3, 0x13, 0x54, 0x7F, 0x90, 0xA1, 0xB2, -0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x12, 0x48, 0x2F, 0x90, 0x9F, 0x13, 0xE0, 0x44, -0x08, 0xF0, 0x22, 0xF0, 0xE4, 0x90, 0xA1, 0xB1, 0xF0, 0x22, 0xE4, 0x90, 0xA1, 0x08, 0xF0, 0xFD, -0xA3, 0x91, 0x92, 0xFB, 0xEB, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, -0x9F, 0x4A, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x9F, 0x4A, -0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xC3, 0x9F, 0xEA, 0x9E, 0x40, 0x23, 0xEB, 0x9F, 0xFF, 0x90, 0x9F, -0x2C, 0xE0, 0xFE, 0xC3, 0x74, 0x0A, 0x9E, 0x2F, 0xFD, 0xC3, 0x94, 0x19, 0x50, 0x0E, 0x74, 0x2F, -0x2D, 0x91, 0x8A, 0xE0, 0x04, 0xF0, 0x90, 0x9F, 0x2A, 0xE0, 0x04, 0xF0, 0x91, 0xB6, 0x90, 0x9F, -0x2A, 0xE0, 0xC3, 0x94, 0x64, 0x40, 0x5F, 0xE4, 0x90, 0xA1, 0x09, 0xF0, 0x90, 0xA1, 0x08, 0xF0, -0x90, 0xA1, 0x08, 0xE0, 0xFF, 0xC3, 0x94, 0x19, 0x50, 0x3F, 0x91, 0x87, 0xE0, 0xFF, 0x90, 0xA1, -0x09, 0xE0, 0x2F, 0xF0, 0xE0, 0xD3, 0x94, 0x05, 0x40, 0x27, 0x90, 0xA1, 0x08, 0xE0, 0xFF, 0x94, -0x0A, 0x40, 0x0A, 0xEF, 0x24, 0xF6, 0x90, 0x9F, 0x29, 0xF0, 0xE4, 0x80, 0x0E, 0xE4, 0x90, 0x9F, -0x29, 0xF0, 0x90, 0xA1, 0x08, 0xE0, 0xFF, 0xC3, 0x74, 0x0A, 0x9F, 0x90, 0x9F, 0x28, 0xF0, 0x80, -0x08, 0x90, 0xA1, 0x08, 0xE0, 0x04, 0xF0, 0x80, 0xB7, 0x90, 0x9F, 0x29, 0xE0, 0xFD, 0x7B, 0x08, -0xE4, 0xFF, 0x91, 0xD9, 0x91, 0x9D, 0x22, 0x74, 0x2F, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x9F, 0xF5, -0x83, 0x22, 0xF0, 0x90, 0x05, 0x62, 0xE0, 0xFE, 0x90, 0x05, 0x61, 0xE0, 0x22, 0xE4, 0xFF, 0x91, -0x87, 0xE4, 0xF0, 0x0F, 0xEF, 0xB4, 0x19, 0xF7, 0xE4, 0x90, 0x9F, 0x2A, 0xF0, 0x90, 0x9F, 0x2E, -0xF0, 0x90, 0x9F, 0x28, 0xF0, 0x22, 0xB1, 0x4F, 0x40, 0x1E, 0x90, 0x9F, 0x2E, 0xE0, 0x04, 0xF0, -0xE0, 0xFF, 0x94, 0x04, 0x50, 0x12, 0x90, 0x9F, 0x28, 0xEF, 0xF0, 0x25, 0xE0, 0x24, 0x08, 0x90, -0x9F, 0x2D, 0xF0, 0xFB, 0xB1, 0x92, 0x91, 0xD9, 0x22, 0xA9, 0x07, 0x90, 0x9F, 0x13, 0xE0, 0x30, -0xE0, 0x41, 0x90, 0x9F, 0x4E, 0xE0, 0x24, 0x03, 0xFF, 0xE4, 0x33, 0xFE, 0x90, 0x9F, 0x29, 0x12, -0x77, 0x9A, 0x50, 0x07, 0x90, 0x9F, 0x1F, 0xEB, 0xF0, 0x80, 0x15, 0xED, 0x24, 0xFD, 0xFF, 0x90, -0x9F, 0x4E, 0xE0, 0x2F, 0x2B, 0x90, 0x9F, 0x1F, 0xF0, 0x90, 0x9F, 0x4E, 0xE0, 0x24, 0x03, 0xFD, -0x90, 0x9F, 0x4E, 0xE0, 0x24, 0x04, 0xC3, 0x9D, 0x29, 0xFF, 0x90, 0x9F, 0x2C, 0xB1, 0x2F, 0xEF, -0xF0, 0x80, 0x0A, 0xB1, 0x30, 0x74, 0x02, 0xF0, 0x90, 0x9F, 0x1F, 0xEB, 0xF0, 0x80, 0x09, 0xF0, -0x90, 0x9F, 0x22, 0xE4, 0xF0, 0xA3, 0x22, 0xF0, 0x90, 0x9F, 0x22, 0xA3, 0xE0, 0x90, 0x05, 0x58, -0xF0, 0x22, 0x90, 0x9F, 0x20, 0xE0, 0x04, 0xF0, 0x90, 0x9F, 0x1B, 0xE0, 0x54, 0xEF, 0xF0, 0x90, -0x9F, 0xB6, 0xE0, 0xFF, 0x90, 0x9F, 0x20, 0xE0, 0xD3, 0x9F, 0x22, 0x12, 0xA2, 0x12, 0x90, 0xA1, -0x18, 0xEF, 0xF0, 0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x5A, -0x26, 0x90, 0xA1, 0x18, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, -0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0xB1, 0x92, 0x90, 0x9F, 0x2D, 0xE0, 0xFB, -0x81, 0xD9, 0x90, 0x9F, 0x28, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x22, 0x12, 0x6F, 0xDF, 0x12, 0x57, -0xC5, 0xFF, 0xF5, 0x55, 0x12, 0x06, 0x89, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, 0x56, 0xBC, -0xF5, 0x56, 0x80, 0x02, 0x8F, 0x56, 0x85, 0x55, 0x54, 0xE5, 0x54, 0xD3, 0x95, 0x56, 0x50, 0x1E, -0x12, 0x57, 0xBD, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFF, 0xB1, 0xF4, 0xEF, 0xF0, 0xB1, 0xF4, 0xE0, -0xAF, 0x54, 0x70, 0x04, 0xF1, 0x71, 0x80, 0x02, 0xF1, 0x64, 0x05, 0x54, 0x80, 0xDB, 0x91, 0x9D, -0xE5, 0x55, 0x70, 0x0F, 0x90, 0x9E, 0x8D, 0xE0, 0x70, 0x09, 0x12, 0x5E, 0xC5, 0x54, 0xBF, 0xF0, -0x54, 0x7F, 0xF0, 0x22, 0x74, 0x8D, 0x25, 0x54, 0xF5, 0x82, 0xE4, 0x34, 0x9E, 0xF5, 0x83, 0x22, -0x90, 0x9F, 0xE6, 0xE0, 0x30, 0xE0, 0x04, 0xD1, 0xDB, 0x80, 0x03, 0x12, 0x86, 0x2E, 0x90, 0xA0, -0x13, 0xE0, 0x30, 0xE0, 0x04, 0xA3, 0xE0, 0x04, 0xF0, 0x90, 0xA0, 0x14, 0xE0, 0x64, 0x08, 0x70, -0x19, 0x90, 0xA0, 0x13, 0xE0, 0x30, 0xE0, 0x0D, 0x12, 0x8A, 0x46, 0xE4, 0xFD, 0x12, 0x46, 0xB5, -0x12, 0x8F, 0xA9, 0x80, 0x05, 0xE4, 0x90, 0xA0, 0x14, 0xF0, 0x90, 0x9F, 0xCE, 0x12, 0x69, 0xCD, -0x30, 0xE0, 0x13, 0x90, 0xA0, 0x15, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x14, 0x09, 0x90, 0x04, 0x9C, -0xE4, 0xF0, 0x90, 0xA0, 0x15, 0xF0, 0x90, 0x9F, 0x0E, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x9F, 0x10, -0x74, 0x01, 0xF0, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x59, 0x90, 0x9F, 0x13, 0xE0, 0x30, 0xE0, 0x1B, -0x90, 0x9F, 0x2B, 0xE0, 0x04, 0x91, 0x92, 0xFD, 0xED, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, -0xD8, 0xF9, 0xFF, 0x90, 0x9F, 0x48, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x9F, 0x14, 0x12, 0x66, -0xE8, 0x30, 0xE0, 0x0C, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x05, 0x12, 0x5F, 0x5B, 0xF1, 0x5A, -0x90, 0xA2, 0x00, 0x12, 0x8F, 0x74, 0xC3, 0x90, 0xA2, 0x01, 0xE0, 0x94, 0x80, 0x90, 0xA2, 0x00, -0xE0, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0x44, -0x01, 0xF0, 0x7F, 0x01, 0x12, 0x86, 0x68, 0x90, 0x9F, 0xBD, 0xE0, 0x30, 0xE0, 0x0C, 0x90, 0x01, -0x3B, 0xE0, 0x30, 0xE4, 0x05, 0x12, 0x5F, 0x5B, 0xF1, 0x51, 0x22, 0x12, 0x66, 0xEF, 0x90, 0x9F, -0xE6, 0x12, 0x86, 0x27, 0xFE, 0xEF, 0xC3, 0x13, 0x54, 0x0F, 0xC3, 0x9E, 0x40, 0x02, 0xE1, 0xAF, -0x90, 0x9F, 0xE6, 0xE0, 0xFF, 0xC3, 0x13, 0x54, 0x0F, 0xFE, 0xEF, 0x54, 0xE1, 0xFF, 0xEE, 0x04, -0x54, 0x0F, 0x25, 0xE0, 0x4F, 0xF0, 0x22, 0x90, 0x9F, 0xBB, 0xE0, 0xFF, 0xC3, 0x13, 0x22, 0x12, -0x06, 0x89, 0x90, 0x9F, 0xBC, 0xF0, 0x60, 0x27, 0x90, 0x9F, 0xCA, 0xE0, 0x20, 0xE0, 0x20, 0xE4, -0xFD, 0x7F, 0x04, 0x12, 0x5A, 0xA8, 0xF1, 0x07, 0x30, 0xE0, 0x14, 0x12, 0x87, 0xBA, 0x20, 0xE0, -0x0E, 0xF1, 0x40, 0x30, 0xE0, 0x04, 0x7F, 0x0D, 0x80, 0x02, 0x7F, 0x09, 0x12, 0x62, 0x14, 0x22, -0x90, 0x9F, 0xBB, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x90, 0x9F, 0x14, 0xE0, 0x54, 0xFB, 0xF0, -0x22, 0x90, 0x9F, 0xBF, 0xE0, 0x90, 0x05, 0x73, 0xF0, 0x22, 0x90, 0x9F, 0x1D, 0xE0, 0x14, 0x90, -0x05, 0x73, 0xF0, 0x22, 0x8F, 0x57, 0x75, 0xF0, 0x10, 0xEF, 0x12, 0x7A, 0x7D, 0x54, 0xFB, 0xF0, -0x22, 0x8F, 0x57, 0x75, 0xF0, 0x10, 0xEF, 0x12, 0x7A, 0x7D, 0x44, 0x04, 0xF0, 0x22, 0x90, 0x9E, -0x8D, 0xE0, 0xB4, 0x01, 0x0F, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x09, 0x51, 0xE6, 0x54, 0x07, 0x70, -0x03, 0x12, 0x68, 0x3E, 0x22, 0x90, 0x9E, 0x8D, 0xE0, 0xB4, 0x01, 0x12, 0x90, 0x9F, 0x17, 0xE0, -0x60, 0x0C, 0x12, 0x6F, 0x95, 0x64, 0x02, 0x60, 0x03, 0x02, 0x87, 0xD8, 0x71, 0x73, 0x22, 0x90, -0x9F, 0xE6, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xE1, 0xF0, 0x90, 0x9F, 0xEB, 0xE0, 0xFF, 0x12, 0x62, -0x14, 0x90, 0x9F, 0xEC, 0x12, 0x62, 0xC8, 0x12, 0x5F, 0x71, 0xE4, 0xFD, 0xFF, 0x02, 0x49, 0x1D, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xEF, 0xB4, 0x03, 0x10, 0x90, 0x9F, 0xCD, 0x12, 0x4F, -0xD2, 0x90, 0x06, 0xCC, 0x30, 0xE0, 0x35, 0xE4, 0xF0, 0x80, 0x34, 0x90, 0x9F, 0xCE, 0xE0, 0xC4, -0x54, 0x0F, 0x30, 0xE0, 0x0C, 0xEF, 0x90, 0x06, 0xCC, 0x70, 0x03, 0xF0, 0x80, 0x03, 0x74, 0x03, -0xF0, 0x90, 0xA0, 0x19, 0xE0, 0x30, 0xE0, 0x17, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x0B, 0xEF, 0x90, -0x06, 0xCC, 0x70, 0x03, 0xF0, 0x80, 0x08, 0x80, 0x03, 0x90, 0x06, 0xCC, 0x74, 0x03, 0xF0, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0x7E, 0x00, 0x7F, 0x0A, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x9F, 0x79, 0xF3, -0x12, 0x08, 0xAA, 0x90, 0x9F, 0xDF, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x9F, 0xCD, 0x12, 0x4F, 0xD2, -0x20, 0xE0, 0x1E, 0x90, 0xFD, 0x62, 0xE0, 0x30, 0xE0, 0x17, 0xE0, 0x90, 0xA1, 0x28, 0x30, 0xE1, -0x05, 0x74, 0x01, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0x90, 0xA1, 0x28, 0xE0, 0xFF, 0x12, 0x64, -0x7E, 0x22, 0x90, 0xA2, 0x0E, 0x12, 0x8F, 0x89, 0x90, 0x9D, 0x94, 0xE0, 0xFF, 0x90, 0xA2, 0x0E, -0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x9D, 0x94, 0xF0, 0x22, 0x90, 0x02, 0x09, 0x11, 0xB5, 0x90, 0x9D, -0x99, 0x12, 0x57, 0xC4, 0x25, 0x51, 0x90, 0x9D, 0x9A, 0x12, 0x56, 0xBB, 0x25, 0x51, 0x90, 0x9D, -0x9B, 0xF0, 0x12, 0x56, 0xE7, 0x25, 0x51, 0x90, 0x9D, 0x9C, 0x12, 0x6C, 0xDD, 0x25, 0x51, 0x90, -0x9D, 0x9D, 0x12, 0x5E, 0x3A, 0x25, 0x51, 0x90, 0x9D, 0x9E, 0xF0, 0x12, 0x5F, 0xE4, 0x25, 0x51, -0x90, 0x9D, 0x9F, 0xF0, 0x22, 0xE0, 0xF5, 0x51, 0x12, 0x06, 0x89, 0x25, 0x51, 0x22, 0x90, 0x04, -0x24, 0x11, 0xB5, 0x90, 0xA0, 0x3B, 0x12, 0x57, 0xC4, 0x25, 0x51, 0x90, 0xA0, 0x49, 0x12, 0x56, -0xBB, 0x25, 0x51, 0x90, 0xA0, 0x57, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, -0x6F, 0xDF, 0x12, 0x06, 0x89, 0xFF, 0x90, 0x9F, 0x0D, 0xF0, 0xBF, 0x01, 0x09, 0x12, 0x57, 0xC5, -0x64, 0x01, 0x60, 0x1C, 0x80, 0x17, 0x12, 0x57, 0xBD, 0x12, 0x57, 0xC5, 0x64, 0x01, 0x60, 0x10, -0x90, 0x9F, 0x0E, 0xE0, 0x20, 0xE0, 0x06, 0xE4, 0xFF, 0x31, 0x15, 0x80, 0x03, 0x12, 0x87, 0x5F, -0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x9F, 0x11, 0xE0, -0x90, 0xA2, 0x10, 0xF0, 0x6F, 0x70, 0x02, 0x41, 0x1E, 0xEF, 0x14, 0x60, 0x42, 0x14, 0x60, 0x6C, -0x14, 0x70, 0x02, 0x21, 0xCA, 0x14, 0x70, 0x02, 0x21, 0xF5, 0x24, 0x04, 0x60, 0x02, 0x41, 0x1E, -0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x04, 0x04, 0x51, 0x49, 0x41, 0x1E, 0x90, 0xA2, 0x10, 0xE0, 0xB4, -0x02, 0x04, 0x51, 0x53, 0x41, 0x1E, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x03, 0x04, 0x51, 0x57, 0x41, -0x1E, 0x90, 0xA2, 0x10, 0xE0, 0x64, 0x01, 0x60, 0x02, 0x41, 0x1E, 0x51, 0x4B, 0x41, 0x1E, 0x90, -0xA2, 0x10, 0xE0, 0xB4, 0x04, 0x04, 0x51, 0x42, 0x41, 0x1E, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x02, -0x04, 0x51, 0x60, 0x41, 0x1E, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x03, 0x04, 0x51, 0x5B, 0x41, 0x1E, -0x90, 0xA2, 0x10, 0xE0, 0x60, 0x02, 0x41, 0x1E, 0x51, 0x23, 0x41, 0x1E, 0x90, 0xA2, 0x10, 0xE0, -0xB4, 0x04, 0x05, 0x12, 0x67, 0xC7, 0x80, 0x76, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x01, 0x05, 0x12, -0x67, 0xB0, 0x80, 0x6A, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x03, 0x05, 0x12, 0x67, 0xBB, 0x80, 0x5E, -0x90, 0xA2, 0x10, 0xE0, 0x70, 0x58, 0x51, 0x73, 0x80, 0x54, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x04, -0x04, 0x51, 0x68, 0x80, 0x49, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x01, 0x04, 0x51, 0x34, 0x80, 0x3E, -0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x02, 0x04, 0x51, 0x78, 0x80, 0x33, 0x90, 0xA2, 0x10, 0xE0, 0x70, -0x2D, 0x51, 0x32, 0x80, 0x29, 0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x03, 0x04, 0x51, 0x7D, 0x80, 0x1E, -0x90, 0xA2, 0x10, 0xE0, 0xB4, 0x01, 0x04, 0x51, 0x2C, 0x80, 0x13, 0x90, 0xA2, 0x10, 0xE0, 0xB4, -0x02, 0x04, 0x51, 0x8B, 0x80, 0x08, 0x90, 0xA2, 0x10, 0xE0, 0x70, 0x02, 0x51, 0x2A, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0x90, 0x9F, 0x11, 0x74, 0x01, 0xF0, 0x22, 0x51, 0x23, 0x7D, 0x1F, 0x51, 0x94, -0xF0, 0x22, 0x51, 0x23, 0x7D, 0x21, 0x7F, 0xFF, 0x12, 0x49, 0x1D, 0x90, 0x9F, 0x11, 0x74, 0x03, -0xF0, 0x22, 0x12, 0x5C, 0x9B, 0x51, 0x83, 0x80, 0xDA, 0x51, 0x42, 0x51, 0xA6, 0xE4, 0x90, 0x9F, -0x11, 0xF0, 0x22, 0x51, 0x60, 0x80, 0xF4, 0x51, 0x5B, 0x80, 0xF0, 0x12, 0x5C, 0x9B, 0x80, 0xC3, -0x12, 0x5F, 0x71, 0x12, 0x5C, 0x9B, 0x80, 0xBB, 0x7D, 0x22, 0x7F, 0xFF, 0x12, 0x49, 0x1D, 0x51, -0x83, 0x80, 0xC8, 0x51, 0x23, 0x02, 0x67, 0xB0, 0x12, 0x5F, 0x71, 0x80, 0xBE, 0x7D, 0x25, 0x51, -0x94, 0xF0, 0x22, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, 0x22, 0x12, 0x5F, 0x71, 0x7D, 0x24, -0x51, 0x94, 0xF0, 0x22, 0x7F, 0x6F, 0x12, 0x49, 0x1D, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0, -0x90, 0x9F, 0x11, 0x74, 0x04, 0x22, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0, 0x22, 0x12, 0x5C, -0x9B, 0x12, 0x5F, 0xEB, 0x51, 0x83, 0x90, 0x9F, 0x12, 0x74, 0x04, 0xF0, 0x22, 0x7D, 0x2E, 0x7F, -0x6F, 0x12, 0x49, 0x1D, 0x7D, 0x02, 0x7F, 0x01, 0x12, 0x5A, 0x26, 0x51, 0xA6, 0x90, 0x9F, 0x12, -0x74, 0x02, 0xF0, 0x22, 0x12, 0x06, 0x89, 0xFF, 0x90, 0x9E, 0x8C, 0xF0, 0xBF, 0x01, 0x08, 0x12, -0x8C, 0x82, 0xE4, 0x90, 0x9E, 0x8C, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFF, 0x90, 0xA0, -0x5A, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x90, 0x9F, 0x21, 0xF0, 0x22, 0x12, -0x6D, 0xF7, 0x90, 0x9F, 0xBD, 0x12, 0x6D, 0x01, 0x12, 0x57, 0xC4, 0x90, 0x9F, 0xBE, 0x12, 0x56, -0xBB, 0x90, 0x9F, 0xBF, 0xF0, 0x90, 0x9F, 0xBE, 0xE0, 0x90, 0x9F, 0xC0, 0xF0, 0x90, 0x9F, 0xBD, -0xE0, 0x54, 0x01, 0xFF, 0x02, 0x5E, 0xD1, 0x12, 0x6D, 0xF7, 0x90, 0x9F, 0xC1, 0xE0, 0x54, 0xFE, -0x4E, 0xF0, 0xEF, 0x54, 0x02, 0x71, 0x49, 0x90, 0x9F, 0x13, 0xE0, 0x54, 0xEF, 0x4F, 0xF0, 0x90, -0x9F, 0xC1, 0xE0, 0x54, 0x01, 0xFF, 0x02, 0x58, 0xE1, 0x33, 0x33, 0x33, 0x54, 0xF8, 0xFF, 0x22, -0x12, 0x06, 0x89, 0x54, 0x01, 0x71, 0x49, 0x90, 0x9F, 0xF0, 0xE0, 0x54, 0xF7, 0x4F, 0xF0, 0x12, -0x66, 0xE8, 0x90, 0x07, 0x65, 0x30, 0xE0, 0x04, 0x74, 0x18, 0xF0, 0x22, 0xE4, 0xF0, 0x22, 0x90, -0x9F, 0xF3, 0xE0, 0x44, 0x10, 0xF0, 0x7D, 0x01, 0x7F, 0x1B, 0x12, 0x86, 0x77, 0x90, 0xA0, 0xEE, -0xEF, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x9F, 0xF4, 0xE0, 0x44, 0x01, -0xF0, 0x7D, 0x01, 0x7F, 0x28, 0x71, 0x7A, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x6F, 0xD2, 0x90, -0xA1, 0xF2, 0xE0, 0x70, 0x08, 0x71, 0xED, 0x90, 0xA1, 0xF2, 0x74, 0x01, 0xF0, 0x12, 0x5E, 0x32, -0x12, 0x06, 0x89, 0xFF, 0xE4, 0x8F, 0x54, 0xF5, 0x53, 0xF5, 0x52, 0xF5, 0x51, 0x90, 0xA0, 0x04, -0x12, 0x45, 0x71, 0xEC, 0x54, 0xC1, 0xFC, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xAF, -0x54, 0xAE, 0x53, 0xAD, 0x52, 0xAC, 0x51, 0x78, 0x19, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, -0xD0, 0x01, 0xD0, 0x00, 0x12, 0x45, 0x53, 0x90, 0xA0, 0x00, 0x02, 0x08, 0x6D, 0x7F, 0x80, 0x7E, -0x08, 0x12, 0x37, 0x4E, 0x90, 0xA0, 0x04, 0x02, 0x08, 0x6D, 0x12, 0x06, 0x89, 0x90, 0xA0, 0x0C, -0x12, 0x57, 0xC4, 0x90, 0xA0, 0x0D, 0xF0, 0x22, 0x12, 0x5E, 0x2C, 0x12, 0x06, 0x89, 0x90, 0xA0, -0x16, 0x12, 0x57, 0xC4, 0x90, 0xA0, 0x17, 0x12, 0x56, 0xBB, 0x90, 0xA0, 0x18, 0xF0, 0x90, 0x9F, -0xF3, 0xE0, 0x44, 0x01, 0xF0, 0x12, 0x5E, 0x32, 0x12, 0x87, 0xAB, 0xB4, 0x02, 0x05, 0x7F, 0x40, -0x12, 0x8B, 0xCF, 0x22, 0x12, 0x06, 0x89, 0xF5, 0x51, 0x12, 0x57, 0xC5, 0xF5, 0x54, 0x12, 0x56, -0xBC, 0xF5, 0x55, 0x12, 0x56, 0xE7, 0xF5, 0x56, 0x12, 0x6C, 0xDE, 0xF5, 0x57, 0x12, 0x5E, 0x3B, -0xF5, 0x58, 0x12, 0x5F, 0xE4, 0xF5, 0x59, 0xE5, 0x51, 0x12, 0x45, 0xC7, 0x9C, 0x75, 0x00, 0x9C, -0x7D, 0x01, 0x9C, 0x85, 0x02, 0x9C, 0x8D, 0x03, 0x9C, 0x95, 0x04, 0x9C, 0x9D, 0x05, 0x9C, 0xA6, -0x06, 0x00, 0x00, 0x9C, 0xB8, 0x75, 0x52, 0x02, 0x75, 0x53, 0x29, 0x80, 0x41, 0x75, 0x52, 0x06, -0x75, 0x53, 0x2A, 0x80, 0x39, 0x75, 0x52, 0x01, 0x75, 0x53, 0x31, 0x80, 0x31, 0x75, 0x52, 0x01, -0x75, 0x53, 0x32, 0x80, 0x29, 0x75, 0x52, 0x06, 0x75, 0x53, 0x33, 0x80, 0x21, 0x7B, 0x00, 0x7A, -0x00, 0x79, 0x54, 0x02, 0x8E, 0xFD, 0x90, 0xA0, 0x0E, 0x91, 0xCB, 0xA3, 0xE5, 0x56, 0xF0, 0xA3, -0xE5, 0x57, 0xF0, 0xA3, 0xE5, 0x58, 0xF0, 0x22, 0x75, 0x52, 0x01, 0x75, 0x53, 0xFF, 0x7B, 0x00, -0x7A, 0x00, 0x79, 0x54, 0xAD, 0x52, 0xAF, 0x53, 0x02, 0x86, 0x77, 0xE5, 0x54, 0xF0, 0xA3, 0xE5, -0x55, 0xF0, 0x22, 0x12, 0x5E, 0x2C, 0x12, 0x06, 0x89, 0x90, 0xA0, 0x29, 0x12, 0x57, 0xC4, 0x90, -0xA0, 0x2A, 0xF0, 0x12, 0x5E, 0x32, 0x7D, 0x02, 0x7F, 0x38, 0x02, 0x86, 0x77, 0x12, 0x06, 0x89, -0x54, 0x01, 0x25, 0xE0, 0x12, 0x8F, 0x98, 0x54, 0xFB, 0x4F, 0xF0, 0xE0, 0x13, 0x13, 0x54, 0x3F, -0x30, 0xE0, 0x02, 0x80, 0x12, 0x90, 0xA0, 0x13, 0xE0, 0x20, 0xE0, 0x02, 0xB1, 0x0F, 0x22, 0x90, -0x07, 0x65, 0xE0, 0x54, 0xE7, 0xF0, 0x22, 0x90, 0x07, 0x65, 0xE0, 0x44, 0x18, 0xF0, 0x22, 0xD3, -0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x9D, 0xF1, 0xE0, 0xFF, 0x90, 0x9D, 0xF0, 0xE0, 0xB5, -0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x3A, 0x90, 0x9D, 0xF0, 0xE0, 0xFE, -0xB1, 0x7A, 0xE0, 0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0xA1, 0xF9, 0x74, 0x9D, 0x35, 0xF0, -0xFA, 0x7B, 0x01, 0xAF, 0x05, 0x12, 0x52, 0xE4, 0x90, 0x9D, 0xF0, 0x12, 0x8F, 0x7B, 0xB4, 0x0A, -0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x9D, 0xF0, 0xF0, 0x12, 0x7D, 0x2B, 0x90, 0x9D, -0x93, 0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0xF0, 0x08, 0x90, 0x9D, 0xA0, -0x02, 0x45, 0xA9, 0xE4, 0x90, 0x9E, 0x88, 0xF0, 0xA3, 0xF0, 0x90, 0x9D, 0xF0, 0xF0, 0xA3, 0xF0, -0x22, 0xE4, 0xFC, 0xED, 0x2C, 0x24, 0x00, 0xB1, 0xE2, 0xE4, 0xF0, 0x0C, 0xEC, 0xB4, 0x18, 0xF3, -0x74, 0x00, 0x2D, 0xB1, 0xE2, 0xEF, 0xF0, 0xEE, 0x54, 0x3F, 0xFF, 0x74, 0x01, 0x2D, 0xF5, 0x82, -0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, -0x83, 0xE0, 0x54, 0xF0, 0xF0, 0x74, 0x03, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, -0x44, 0x80, 0xF0, 0x74, 0x0B, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x44, 0x10, -0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, -0xD0, 0x90, 0xA1, 0xD8, 0x12, 0x45, 0xBE, 0x7F, 0x96, 0x7E, 0x02, 0x12, 0x8F, 0x33, 0xEF, 0x60, -0x51, 0x90, 0x01, 0x17, 0xE0, 0xFE, 0x90, 0x01, 0x16, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF, 0xEC, -0x3E, 0xFE, 0xEF, 0x24, 0x01, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0xA1, 0xDB, 0xEF, 0xF0, 0xEE, 0xFF, -0x90, 0xFD, 0x11, 0xF0, 0x90, 0xA1, 0xDB, 0xE0, 0xFD, 0x90, 0x02, 0x94, 0xF0, 0xA3, 0xEF, 0xF0, -0x90, 0xA1, 0xD8, 0xD1, 0xC9, 0x24, 0x02, 0xFF, 0xE4, 0x33, 0xFE, 0xB1, 0x91, 0x90, 0xA1, 0xDB, -0xE0, 0x24, 0x18, 0xFF, 0x90, 0xA1, 0xD8, 0x12, 0x45, 0xB5, 0xD1, 0x57, 0x90, 0x02, 0x96, 0x74, -0x01, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA1, 0xD4, 0xEF, 0xF0, 0xA3, 0x12, 0x45, 0xBE, -0x90, 0xA1, 0xF4, 0xE0, 0xFE, 0x04, 0xF0, 0x90, 0x00, 0x01, 0xEE, 0x12, 0x06, 0xE1, 0x74, 0x00, -0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0xA1, -0xD5, 0x12, 0x45, 0xB5, 0x8B, 0x40, 0x8A, 0x41, 0x89, 0x42, 0x75, 0x43, 0x02, 0xD0, 0x01, 0xD0, -0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, 0xA1, 0xD4, 0xE0, 0x24, 0x02, 0xF9, 0xE4, 0x34, 0xFB, -0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0xA3, 0x12, 0x45, 0xB5, 0xE9, 0x24, 0x02, -0xF9, 0xE4, 0x3A, 0x8B, 0x40, 0xF5, 0x41, 0x89, 0x42, 0x90, 0xA1, 0xD5, 0xD1, 0xC9, 0xF5, 0x43, -0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x02, 0x35, 0x26, 0x12, 0x45, 0xB5, 0x90, 0x00, 0x0E, 0x02, -0x06, 0xA2, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0x90, 0x9E, 0x89, 0xE0, 0xFE, -0x90, 0x9E, 0x88, 0xE0, 0xFD, 0xB5, 0x06, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x64, -0x01, 0x60, 0x24, 0xED, 0x12, 0x8F, 0xB4, 0xFA, 0x7B, 0x01, 0xB1, 0xEA, 0x7F, 0x01, 0xEF, 0x60, -0x16, 0x90, 0x9E, 0x88, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x02, 0x80, 0x02, 0x7F, 0x00, 0xEF, -0x60, 0x05, 0xE4, 0x90, 0x9E, 0x88, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA1, 0xF5, 0x12, -0x45, 0xBE, 0xE4, 0xFF, 0x90, 0xA1, 0xF5, 0x12, 0x45, 0xB5, 0x8F, 0x82, 0x75, 0x83, 0x00, 0x12, -0x06, 0xA2, 0xFE, 0x74, 0xF0, 0x2F, 0xF1, 0x40, 0xEE, 0xF0, 0x0F, 0xEF, 0xB4, 0x10, 0xE5, 0x22, -0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, 0x22, 0x90, 0x00, 0xF1, 0xE0, 0x54, 0xF0, 0xC4, 0x54, -0x0F, 0xFF, 0x22, 0x75, 0x15, 0x12, 0xE4, 0xF5, 0x16, 0x75, 0x17, 0x07, 0x75, 0x18, 0x32, 0x90, -0x01, 0x30, 0xE5, 0x15, 0xF0, 0xA3, 0xE5, 0x16, 0xF0, 0xA3, 0xE5, 0x17, 0xF0, 0xA3, 0xE5, 0x18, -0xF0, 0x22, 0x75, 0x1D, 0x06, 0x75, 0x1E, 0x01, 0x75, 0x1F, 0x03, 0x75, 0x20, 0x62, 0x43, 0x20, -0x80, 0x43, 0x1F, 0x04, 0x90, 0x01, 0x38, 0xE5, 0x1D, 0xF0, 0xA3, 0xE5, 0x1E, 0xF0, 0xA3, 0xE5, -0x1F, 0xF0, 0xA3, 0xE5, 0x20, 0xF0, 0x22, 0x90, 0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01, -0xC7, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x44, 0x0B, 0x12, 0x8F, 0x90, 0x90, -0x01, 0x98, 0xE0, 0x54, 0xC0, 0x7F, 0x00, 0xB4, 0x40, 0x02, 0x7F, 0x01, 0x22, 0xE4, 0x90, 0xA0, -0xDE, 0xF0, 0xA3, 0xF0, 0xF1, 0xA4, 0xEF, 0x64, 0x01, 0x60, 0x3D, 0xC3, 0x90, 0xA0, 0xDF, 0xE0, -0x94, 0x88, 0x90, 0xA0, 0xDE, 0xE0, 0x94, 0x13, 0x40, 0x0F, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x10, -0xF0, 0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0, 0x80, 0x1F, 0x90, 0xA0, 0xDE, 0x12, 0x8F, 0x74, 0x12, -0x8F, 0x82, 0xD3, 0x90, 0xA0, 0xDF, 0xE0, 0x94, 0x32, 0x90, 0xA0, 0xDE, 0xE0, 0x94, 0x00, 0x40, -0xC3, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE3, 0xBC, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22, 0x7D, -0x02, 0x90, 0x01, 0xC4, 0x74, 0x0F, 0xF0, 0x74, 0xA0, 0xA3, 0xF0, 0x90, 0xA0, 0x2B, 0xE0, 0xFF, -0xED, 0xC3, 0x9F, 0x50, 0x10, 0xED, 0x25, 0xE0, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x03, 0x7F, -0x00, 0x22, 0x0D, 0x80, 0xE6, 0x7F, 0x01, 0x22, 0xE4, 0x90, 0x9D, 0x93, 0x12, 0x58, 0xB2, 0xA3, -0xF0, 0x22, 0x90, 0x01, 0xE4, 0x74, 0x1D, 0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x34, 0xE0, -0x55, 0x15, 0xF5, 0x19, 0xA3, 0xE0, 0x55, 0x16, 0xF5, 0x1A, 0xA3, 0xE0, 0x55, 0x17, 0xF5, 0x1B, -0xA3, 0xE0, 0x55, 0x18, 0xF5, 0x1C, 0x90, 0x01, 0x34, 0xE5, 0x19, 0xF0, 0xA3, 0xE5, 0x1A, 0xF0, -0xA3, 0xE5, 0x1B, 0xF0, 0xA3, 0xE5, 0x1C, 0xF0, 0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x1D, 0xF5, -0x21, 0xA3, 0xE0, 0x55, 0x1E, 0xF5, 0x22, 0xA3, 0xE0, 0x55, 0x1F, 0xF5, 0x23, 0xA3, 0xE0, 0x55, -0x20, 0xF5, 0x24, 0x90, 0x01, 0x3C, 0xE5, 0x21, 0xF0, 0xA3, 0xE5, 0x22, 0xF0, 0xA3, 0xE5, 0x23, -0xF0, 0xA3, 0xE5, 0x24, 0xF0, 0x53, 0x91, 0xDF, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90, 0xA1, 0x08, -0xF0, 0xE0, 0xFF, 0x30, 0xE0, 0x07, 0x90, 0x01, 0xCF, 0xE0, 0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE5, -0x23, 0x90, 0x01, 0xCF, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0xE4, 0xF5, -0xA8, 0xF5, 0xE8, 0x12, 0x58, 0x8C, 0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, -0x46, 0xA0, 0x80, 0xFE, 0x22, 0x90, 0x9F, 0x0E, 0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xA3, 0xF0, 0xA3, -0xF0, 0x22, 0x90, 0x9F, 0x17, 0xE0, 0x70, 0x07, 0x90, 0x9F, 0x0E, 0xE0, 0x30, 0xE0, 0x13, 0x90, -0x9F, 0x0E, 0xE0, 0x30, 0xE0, 0x09, 0x12, 0x6E, 0x19, 0xBF, 0x01, 0x06, 0x02, 0x6F, 0x76, 0x12, -0x5C, 0xD8, 0x22, 0x90, 0x9F, 0x17, 0xE0, 0x60, 0x03, 0x12, 0x6E, 0xC2, 0x02, 0x48, 0x5C, 0x90, -0x9F, 0x0E, 0xE0, 0xFF, 0x30, 0xE0, 0x3F, 0x90, 0x9F, 0x12, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02, -0x7E, 0x01, 0x90, 0x9F, 0x11, 0xE0, 0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70, -0x25, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x03, 0x02, 0x87, 0x5F, 0x12, 0x6E, 0xEC, 0x90, 0x9F, 0x12, -0xE0, 0xB4, 0x08, 0x06, 0xE4, 0xFD, 0x7F, 0x0C, 0x80, 0x09, 0x90, 0x9F, 0x12, 0xE0, 0x70, 0x06, -0xFD, 0x7F, 0x04, 0x12, 0x5A, 0xA8, 0x22, 0x90, 0x9F, 0x0E, 0xE0, 0xFF, 0x30, 0xE0, 0x40, 0x90, -0x9F, 0x12, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02, 0x7E, 0x01, 0x90, 0x9F, 0x11, 0xE0, 0x7D, 0x00, -0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70, 0x26, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x03, 0x02, -0x87, 0x5F, 0x12, 0x92, 0x02, 0x90, 0x9F, 0x12, 0xE0, 0xB4, 0x0C, 0x06, 0xE4, 0xFD, 0x7F, 0x08, -0x80, 0x0A, 0x90, 0x9F, 0x12, 0xE0, 0xB4, 0x04, 0x06, 0xE4, 0xFD, 0xFF, 0x12, 0x5A, 0xA8, 0x22, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA0, 0x19, 0xE0, 0x30, 0xE0, 0x21, 0x90, 0xA0, -0x1E, 0xE0, 0xB4, 0x01, 0x0D, 0xA3, 0xE0, 0xB4, 0x01, 0x15, 0x74, 0x02, 0xF0, 0x12, 0x67, 0x89, -0x80, 0x0D, 0x90, 0xA0, 0x1E, 0xE0, 0xB4, 0x02, 0x06, 0x74, 0x03, 0xF0, 0x12, 0x67, 0x14, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x04, 0x1D, 0xE0, 0x60, -0x1A, 0x90, 0x05, 0x22, 0xE0, 0x54, 0x90, 0x60, 0x07, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x08, 0xF0, -0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE1, 0xE4, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, -0xAF, 0x22, 0xE4, 0x90, 0xA1, 0x19, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x7F, 0x83, 0x12, 0x47, 0xBF, -0x90, 0xA1, 0x19, 0xEF, 0xF0, 0x7F, 0x83, 0x12, 0x47, 0xBF, 0xAE, 0x07, 0x90, 0xA1, 0x19, 0xE0, -0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3, 0x90, 0xA1, 0x1B, 0xE0, 0x94, 0x64, 0x90, 0xA1, 0x1A, 0xE0, -0x94, 0x00, 0x40, 0x0D, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0xA1, 0x19, 0xE0, 0xFF, -0x22, 0x90, 0xA1, 0x1A, 0x12, 0x8F, 0x74, 0x80, 0xC2, 0x90, 0x01, 0xC4, 0x74, 0x59, 0xF0, 0x74, -0xA2, 0xA3, 0xF0, 0x7F, 0x90, 0x12, 0x47, 0xBF, 0xEF, 0x20, 0xE0, 0xF7, 0x74, 0x59, 0x04, 0x90, -0x01, 0xC4, 0xF0, 0x74, 0xA2, 0xA3, 0xF0, 0x22, 0xE4, 0xF5, 0x5E, 0x12, 0x56, 0xD4, 0xE0, 0xFE, -0xB4, 0x02, 0x08, 0xED, 0xC3, 0x94, 0x11, 0x40, 0x22, 0x80, 0x18, 0xEE, 0xB4, 0x01, 0x08, 0xED, -0xC3, 0x94, 0x0A, 0x40, 0x16, 0x80, 0x0C, 0x12, 0x56, 0xD4, 0xE0, 0x70, 0x0B, 0xED, 0xC3, 0x94, -0x03, 0x40, 0x08, 0x75, 0x5E, 0x01, 0x80, 0x03, 0xE4, 0xF5, 0x5E, 0xAF, 0x5E, 0x22, 0x8F, 0x52, -0x8D, 0x53, 0x8B, 0x54, 0x12, 0x56, 0xC2, 0xE0, 0xFF, 0x75, 0xF0, 0x04, 0xE5, 0x52, 0x12, 0x77, -0x94, 0xE0, 0xFD, 0x2F, 0x51, 0xF3, 0x90, 0xA0, 0xF1, 0xF0, 0xE5, 0x53, 0xD3, 0x94, 0x2D, 0x40, -0x02, 0x80, 0x16, 0xE5, 0x53, 0xD3, 0x94, 0x19, 0x40, 0x05, 0x90, 0xA0, 0xF1, 0x80, 0x08, 0x75, -0xF0, 0x04, 0xE5, 0x52, 0x12, 0x56, 0xC6, 0xE0, 0xFD, 0x85, 0x54, 0x6A, 0xE4, 0xFB, 0xAF, 0x52, -0x02, 0x75, 0xDD, 0xFF, 0xE4, 0x33, 0xA2, 0xE7, 0x13, 0xEF, 0x13, 0x22, 0xD3, 0x10, 0xAF, 0x01, -0xC3, 0xC0, 0xD0, 0xED, 0x60, 0x2C, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x8D, 0x01, 0x71, 0x4A, 0xEF, -0x90, 0x8D, 0x03, 0x71, 0x4A, 0xEF, 0x90, 0x8D, 0x05, 0x71, 0x4A, 0xEF, 0x90, 0x8D, 0x07, 0x71, -0x4A, 0xEF, 0x90, 0x8D, 0x09, 0x71, 0x55, 0x12, 0x77, 0xD5, 0xE4, 0xF0, 0xA3, 0xF0, 0x71, 0x5C, -0xE4, 0xF0, 0x71, 0x67, 0x54, 0xBF, 0x44, 0x80, 0xFE, 0x75, 0xF0, 0x10, 0xEF, 0x90, 0x81, 0x03, -0x12, 0x45, 0xA9, 0xEE, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x45, 0xA9, 0xE4, 0xF0, 0xA3, -0xF0, 0x75, 0xF0, 0x0A, 0x22, 0x12, 0x45, 0xA9, 0xE4, 0xF0, 0xA3, 0x22, 0x74, 0x12, 0x2F, 0xF5, -0x82, 0xE4, 0x34, 0x98, 0xF5, 0x83, 0x22, 0x75, 0xF0, 0x10, 0xEF, 0x90, 0x81, 0x03, 0x12, 0x45, -0xA9, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x08, 0xEF, 0xF0, 0x71, -0xC9, 0x30, 0xE6, 0x40, 0x7F, 0x8D, 0x12, 0x47, 0xBF, 0xEF, 0x64, 0x01, 0x70, 0x36, 0x90, 0xA2, -0x09, 0xF0, 0x90, 0xA2, 0x09, 0xE0, 0xFD, 0x90, 0xA2, 0x08, 0xE0, 0x75, 0xF0, 0x10, 0x90, 0x81, -0x00, 0x12, 0x45, 0xA9, 0xE5, 0x82, 0x2D, 0x12, 0x56, 0x0E, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x50, -0xBA, 0x90, 0xA2, 0x09, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x10, 0x40, 0xD5, 0x71, 0xC9, 0x30, -0xE0, 0x02, 0x71, 0xD0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x8F, 0x12, 0x47, 0xBF, 0xEF, 0x22, -0xE4, 0xFD, 0x7F, 0x8D, 0x02, 0x46, 0xA0, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, -0x4C, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0xA1, 0x4B, 0xEF, 0xF0, 0xA3, 0xA3, 0xE0, 0xFD, 0x12, -0x3E, 0x02, 0x90, 0xA1, 0x56, 0x12, 0x08, 0x6D, 0x90, 0xA1, 0x4E, 0x12, 0x45, 0x71, 0x12, 0x08, -0x3A, 0x90, 0xA1, 0x56, 0x12, 0x4F, 0xEF, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, -0xA1, 0x4E, 0x12, 0x45, 0x71, 0x90, 0xA1, 0x52, 0x12, 0x4F, 0xEF, 0xD0, 0x03, 0xD0, 0x02, 0xD0, -0x01, 0xD0, 0x00, 0x12, 0x45, 0x53, 0x90, 0xA1, 0x5A, 0x12, 0x08, 0x6D, 0x90, 0xA1, 0x4C, 0xA3, -0xE0, 0xFD, 0xC0, 0x05, 0x90, 0xA1, 0x5A, 0x12, 0x45, 0x71, 0x90, 0xAA, 0x96, 0x12, 0x08, 0x6D, -0x90, 0xA1, 0x4B, 0xE0, 0xFF, 0xD0, 0x05, 0x12, 0x3D, 0x09, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, -0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xE0, 0xEF, 0xF0, 0xED, 0x64, 0x01, 0x70, 0x2E, -0xEB, 0xB4, 0x01, 0x07, 0xE0, 0x24, 0x02, 0xF5, 0x72, 0x80, 0x08, 0x90, 0xA1, 0xE0, 0xE0, 0x24, -0xFE, 0xF5, 0x72, 0x90, 0xA1, 0x4E, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0x72, 0x91, -0xC0, 0x91, 0xB8, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0x72, 0x80, 0x1F, 0x90, 0xA1, -0x4E, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0x90, 0xA1, 0xE0, 0xE0, 0xFF, 0x91, 0xC0, 0x91, -0xB8, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0x90, 0xA1, 0xE0, 0xE0, 0xFF, 0x91, 0xC0, 0x7F, -0x01, 0x71, 0xD7, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xFF, 0x71, 0xD7, 0x90, 0xA1, 0x4E, 0x22, -0xE4, 0xFC, 0xFD, 0xFE, 0x90, 0xA1, 0x52, 0x12, 0x08, 0x6D, 0x7D, 0x18, 0x7C, 0x00, 0x22, 0x7E, -0x00, 0x7F, 0x2D, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0x2C, 0x02, 0x08, 0xAA, 0xC3, 0xEF, -0x9D, 0xF5, 0x56, 0xC3, 0x94, 0x08, 0x50, 0x1C, 0xE4, 0xF5, 0x57, 0xB1, 0xB8, 0xC0, 0x83, 0xC0, -0x82, 0x90, 0xA0, 0xF2, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0x75, 0xF0, 0x03, 0x12, 0x45, 0xA9, 0xE5, -0x56, 0xF0, 0x80, 0x3E, 0xE5, 0x56, 0xC3, 0x94, 0x10, 0x50, 0x09, 0x75, 0x57, 0x01, 0xE5, 0x56, -0x24, 0xF8, 0x80, 0x17, 0xE5, 0x56, 0xC3, 0x94, 0x18, 0x50, 0x09, 0x75, 0x57, 0x02, 0xE5, 0x56, -0x24, 0xF0, 0x80, 0x07, 0x75, 0x57, 0x03, 0xE5, 0x56, 0x24, 0xE8, 0xFF, 0xB1, 0xB8, 0xC0, 0x83, -0xC0, 0x82, 0x90, 0xA0, 0xF2, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0x75, 0xF0, 0x03, 0x12, 0x45, 0xA9, -0xEF, 0xF0, 0xAF, 0x57, 0x22, 0x8F, 0x54, 0x8D, 0x55, 0xAE, 0x03, 0x74, 0x1F, 0xC3, 0x95, 0x54, -0x40, 0x0A, 0xB1, 0xB0, 0xE4, 0xFD, 0xB1, 0xA8, 0x24, 0xD4, 0x80, 0x31, 0x74, 0x3F, 0xC3, 0x95, -0x54, 0x40, 0x0A, 0xB1, 0xB0, 0x7D, 0x20, 0xB1, 0xA6, 0x24, 0x88, 0x80, 0x20, 0x74, 0x5F, 0xC3, -0x95, 0x54, 0x40, 0x0A, 0xB1, 0xB0, 0x7D, 0x40, 0xB1, 0xA6, 0x24, 0xD0, 0x80, 0x0F, 0x74, 0x7F, -0xC3, 0x95, 0x54, 0x40, 0x20, 0xB1, 0xB0, 0x7D, 0x60, 0xB1, 0xA6, 0x24, 0x84, 0xFD, 0xE4, 0x34, -0x04, 0xFC, 0x75, 0xF0, 0x0E, 0xE5, 0x55, 0xB1, 0xC5, 0x75, 0xF0, 0x03, 0xEE, 0x12, 0x45, 0xA9, -0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x22, 0xAF, 0x54, 0x91, 0xDE, 0x90, 0xA0, 0xEE, 0xEF, 0xF0, 0x22, -0x90, 0xA0, 0xF2, 0xEE, 0xF0, 0xAB, 0x55, 0x22, 0x75, 0xF0, 0x0E, 0xEB, 0x90, 0xA0, 0x33, 0x02, -0x45, 0xA9, 0x75, 0xF0, 0x0E, 0x90, 0xA0, 0x31, 0x02, 0x45, 0xA9, 0x90, 0xA0, 0x2C, 0xE0, 0x30, -0xE0, 0x22, 0xB1, 0xF5, 0xE0, 0xFE, 0x30, 0xE0, 0x1B, 0x75, 0xF0, 0x0E, 0xEF, 0xB1, 0xFD, 0xEE, -0x54, 0xFE, 0xF0, 0x90, 0xA0, 0x2E, 0x74, 0x05, 0xF0, 0x12, 0x4A, 0x47, 0x54, 0x07, 0xFD, 0x7F, -0x01, 0x12, 0x49, 0xA0, 0x22, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0x75, 0xF0, 0x0E, 0x90, 0xA0, 0x37, -0x02, 0x45, 0xA9, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x37, -0x4E, 0x90, 0xA0, 0xE1, 0x12, 0x08, 0x6D, 0x7F, 0x00, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0x90, 0xA0, -0xE5, 0x12, 0x08, 0x6D, 0x90, 0xA0, 0xE1, 0xD1, 0x70, 0x60, 0x18, 0x90, 0xA0, 0xE1, 0xD1, 0x67, -0x90, 0xA0, 0xE1, 0x12, 0x08, 0x6D, 0x90, 0xA0, 0xE1, 0x12, 0x47, 0xDF, 0x7F, 0x00, 0x7E, 0x08, -0x12, 0x38, 0x45, 0x90, 0xA0, 0xE5, 0xD1, 0x70, 0x60, 0x18, 0x90, 0xA0, 0xE5, 0xD1, 0x67, 0x90, -0xA0, 0xE5, 0x12, 0x08, 0x6D, 0x90, 0xA0, 0xE5, 0x12, 0x47, 0xDF, 0x7F, 0x00, 0x7E, 0x09, 0x12, -0x38, 0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x45, 0x71, 0xEF, 0x54, 0xFE, 0xFF, 0xEC, 0x22, -0x12, 0x45, 0x71, 0xEF, 0x54, 0x01, 0xFF, 0xE4, 0xFE, 0xFD, 0xFC, 0xEF, 0x22, 0xE4, 0x90, 0x9E, -0x8D, 0xF0, 0x22, 0x7E, 0x00, 0x7F, 0x01, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x9F, 0x79, 0x0E, 0x12, -0x08, 0xAA, 0x90, 0x9F, 0x0E, 0xE0, 0x54, 0xFD, 0xF0, 0xE4, 0x12, 0x58, 0xB3, 0xA3, 0x74, 0x0C, -0xF0, 0x22, 0x90, 0x9F, 0x13, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0x90, 0x9F, 0x20, 0xF0, 0x90, 0x9F, -0x1B, 0xF0, 0x90, 0x9F, 0x14, 0xE0, 0x54, 0xF7, 0xF0, 0x12, 0x5E, 0xB4, 0x7D, 0x02, 0x7F, 0x02, -0x02, 0x5E, 0xB8, 0xEF, 0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70, 0x27, 0x90, 0x9F, 0x1D, 0x74, 0x02, -0xF0, 0x80, 0x16, 0xED, 0x70, 0x0A, 0x90, 0x9F, 0xB9, 0xE0, 0x90, 0x9F, 0x1D, 0xF0, 0x80, 0x05, -0x90, 0x9F, 0x1D, 0xED, 0xF0, 0x90, 0x9F, 0x1D, 0xE0, 0xA3, 0xF0, 0x90, 0x9F, 0x14, 0xE0, 0x44, -0x08, 0xF0, 0x22, 0x90, 0x9F, 0xCA, 0xE0, 0x30, 0xE0, 0x17, 0x90, 0x9F, 0xDD, 0xE0, 0x70, 0x60, -0x90, 0x9F, 0x19, 0xE0, 0xD3, 0x94, 0x00, 0x50, 0x57, 0x90, 0x9F, 0xBC, 0xE0, 0x60, 0x4E, 0x80, -0x4F, 0x12, 0x6F, 0x9C, 0xEF, 0x64, 0x01, 0x70, 0x47, 0x90, 0x9F, 0x1B, 0xE0, 0xFF, 0x54, 0x03, -0x70, 0x3E, 0x90, 0x9F, 0x19, 0xE0, 0xFE, 0xE4, 0xC3, 0x9E, 0x40, 0x34, 0xEF, 0x20, 0xE2, 0x30, -0x90, 0x9F, 0x1B, 0xE0, 0x20, 0xE4, 0x29, 0x90, 0x9F, 0x14, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, -0xE0, 0x1E, 0x90, 0x9F, 0xBC, 0xE0, 0x70, 0x18, 0x90, 0x06, 0x62, 0xE0, 0x20, 0xE1, 0x11, 0x90, -0x06, 0x62, 0xE0, 0x30, 0xE0, 0x07, 0xE0, 0x54, 0xFC, 0x64, 0x80, 0x60, 0x03, 0x7F, 0x01, 0x22, -0x7F, 0x00, 0x22, 0x90, 0x9F, 0xBD, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x13, 0x90, 0x02, 0x87, 0xE0, -0x70, 0x17, 0x90, 0x02, 0x96, 0xE0, 0x70, 0x11, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE1, 0x0A, 0x90, -0xA0, 0x13, 0xE0, 0x20, 0xE0, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x9F, 0xC6, 0xE0, -0x90, 0x01, 0x30, 0xF0, 0x90, 0x9F, 0xC3, 0xE0, 0x90, 0x01, 0x39, 0xF0, 0x90, 0x9F, 0xC4, 0xE0, -0x90, 0x01, 0x3A, 0xF0, 0x22, 0x90, 0xA1, 0xC0, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x81, 0x00, -0xE0, 0x54, 0x0F, 0xFD, 0xAC, 0x07, 0x12, 0xA9, 0x32, 0x44, 0x01, 0xF0, 0x12, 0xA9, 0x32, 0x54, -0xFB, 0xF0, 0xAC, 0x07, 0x74, 0x12, 0x2C, 0x12, 0x4F, 0x92, 0xE0, 0x44, 0xFA, 0xF0, 0x74, 0x11, -0x2C, 0x12, 0xAA, 0x61, 0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5, 0x82, 0xE4, -0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0E, 0xF0, 0x90, 0x04, 0xA7, 0xE4, 0xF0, 0x90, 0x04, 0xA6, -0xF0, 0x90, 0x04, 0xA5, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0xA4, 0x74, 0xFD, 0xF0, 0x74, 0x14, 0x2C, -0x11, 0x0F, 0xE0, 0x54, 0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F, 0x11, 0x0F, 0xED, 0xF0, 0x22, 0xF5, -0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90, 0xA1, 0xBE, 0xE0, 0xFF, 0xD3, 0x10, 0xAF, 0x01, -0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x14, 0xEF, 0xF0, 0x90, 0x9D, 0x9B, 0xE0, 0xFF, 0x90, 0x04, 0x1C, -0xE0, 0x6F, 0x70, 0x3E, 0x90, 0x9F, 0x1A, 0xE0, 0x64, 0x0E, 0x70, 0x15, 0x90, 0xA2, 0x14, 0xE0, -0x70, 0x30, 0x90, 0x9F, 0x13, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06, 0x04, 0x12, 0x5A, 0x1E, 0x80, -0x1E, 0x90, 0x9F, 0x1A, 0xE0, 0x64, 0x06, 0x70, 0x19, 0x90, 0xA2, 0x14, 0xE0, 0x60, 0x13, 0x90, -0x9F, 0x13, 0xE0, 0x54, 0xBF, 0xF0, 0x11, 0x77, 0xF0, 0x90, 0x9F, 0x1A, 0x74, 0x04, 0xF0, 0x12, -0x5C, 0x9B, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x40, 0xF0, 0xE0, 0x44, -0x80, 0x22, 0x90, 0x9D, 0x9E, 0xE0, 0xFF, 0xE4, 0xFB, 0x7D, 0x01, 0x12, 0x4D, 0x56, 0x90, 0xA1, -0xC5, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA1, 0xC3, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xD3, 0x10, -0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAB, 0x07, 0x90, 0xA2, 0x15, 0xED, 0xF0, 0xEC, 0xF9, 0xE0, 0xFF, -0xAE, 0x03, 0x74, 0x2A, 0x2E, 0x11, 0xC1, 0x12, 0x4F, 0x9A, 0xE9, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, -0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x22, 0xE4, 0xFE, 0xEF, 0xC3, 0x13, -0xFD, 0xEF, 0x30, 0xE0, 0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED, 0xF0, 0xAF, 0x06, 0x22, 0x90, -0x9D, 0x9C, 0xE0, 0xFF, 0x7B, 0x08, 0x7D, 0x01, 0x12, 0x4D, 0x56, 0x90, 0xA1, 0xE9, 0xEE, 0xF0, -0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0xA1, 0xE8, 0xE0, 0x22, 0x7F, 0xA3, 0x12, 0x47, 0xBF, 0xEF, -0x54, 0xF8, 0x44, 0x05, 0xFD, 0x7F, 0xA3, 0x12, 0x46, 0xA0, 0x7F, 0xA0, 0x12, 0x47, 0xBF, 0xEF, -0x54, 0x0F, 0x64, 0x04, 0x22, 0x75, 0xF0, 0x03, 0x12, 0x45, 0xA9, 0xE0, 0xFE, 0x74, 0x01, 0xA8, -0x06, 0x08, 0x22, 0x90, 0xA2, 0x0F, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0xEF, 0x54, 0x03, 0xFF, -0xE4, 0x22, 0x74, 0x0D, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xFD, 0x7C, -0x00, 0x12, 0x07, 0x03, 0xEF, 0x25, 0x55, 0xF5, 0x55, 0xEE, 0x35, 0x54, 0xF5, 0x54, 0x22, 0x90, -0x9F, 0x4E, 0xE0, 0x24, 0x04, 0x90, 0x9F, 0x2C, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x22, 0xA4, 0xF5, -0x82, 0x85, 0xF0, 0x83, 0x12, 0x07, 0xAB, 0xAE, 0xF0, 0xA8, 0x59, 0x08, 0x22, 0xFD, 0x75, 0xF0, -0x0E, 0x90, 0xA0, 0x2F, 0x02, 0x45, 0xA9, 0x7E, 0x00, 0x7F, 0x04, 0x7D, 0x00, 0x7B, 0x01, 0x7A, -0x9F, 0x79, 0xBD, 0x22, 0x12, 0x45, 0xA9, 0xE0, 0xFC, 0xA3, 0xE0, 0xF5, 0x82, 0x8C, 0x83, 0x22, -0x12, 0x45, 0xA9, 0xE0, 0xFE, 0xED, 0xFF, 0x90, 0xA0, 0x5C, 0xE0, 0x22, 0x74, 0x21, 0x2F, 0xF5, -0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x93, -0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x9B, 0xF5, 0x83, 0xE5, 0x5F, 0xF0, 0x22, 0xFE, 0x54, -0x03, 0xFF, 0xEE, 0x13, 0x13, 0x54, 0x07, 0x22, 0x90, 0x01, 0x53, 0x74, 0x03, 0xF0, 0x7D, 0x10, -0xFF, 0x22, 0x90, 0xA0, 0x2C, 0xE0, 0xFE, 0xC3, 0x13, 0x54, 0x07, 0x22, 0x90, 0xA1, 0xE7, 0xE0, -0xFF, 0x90, 0xA1, 0xE5, 0xE0, 0x22, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0x75, 0xF0, 0x08, 0x22, -0x7F, 0x16, 0x12, 0x47, 0xBF, 0xEF, 0x54, 0x0F, 0x22, 0x7F, 0x30, 0x7E, 0x09, 0x12, 0x37, 0x4E, -0xE4, 0x22, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, 0x22, 0x90, 0xA0, 0x5C, 0xE0, 0xFF, -0xC3, 0x94, 0x80, 0x22, 0xE5, 0x6C, 0x75, 0xF0, 0x08, 0xA4, 0x25, 0x6B, 0x22, 0xFF, 0x90, 0xA1, -0xDE, 0xE0, 0xFB, 0xEF, 0x5B, 0x22, 0x90, 0x9F, 0xD1, 0xE0, 0x54, 0xDF, 0xF0, 0xE4, 0x22, 0x90, -0xA1, 0xCF, 0xE0, 0x7F, 0x48, 0x7E, 0x09, 0x22, 0x90, 0x9F, 0xCD, 0xE0, 0xC4, 0x13, 0x54, 0x07, -0x22, 0xF0, 0x7F, 0x10, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, -0x22, 0xFF, 0x12, 0x06, 0x89, 0x54, 0x0F, 0xFD, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F, 0xF0, -0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xC4, 0x54, 0x0F, 0x90, 0xA1, 0xE3, 0xF0, -0x22, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0xF0, 0x10, 0x22, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x6B, 0x08, -0x22, 0x75, 0xF0, 0x10, 0xEF, 0x90, 0x81, 0x00, 0x22, 0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, -0x22, 0x12, 0x47, 0xBF, 0xEF, 0x44, 0x40, 0xFD, 0x22, 0x00, 0xDE, 0xF2, +0xF0, 0xD0, 0xE0, 0x32, 0x90, 0xFD, 0x68, 0xE0, 0xFF, 0x90, 0xFD, 0x60, 0xE0, 0x90, 0xA1, 0x3A, +0xF0, 0xEF, 0x20, 0xE0, 0x02, 0x21, 0xF9, 0x90, 0xA2, 0x16, 0xE0, 0x70, 0x1A, 0x7F, 0x2E, 0x12, +0x47, 0xAF, 0x90, 0xA0, 0x9C, 0xEF, 0xF0, 0x7F, 0x2D, 0x12, 0x47, 0xAF, 0x90, 0xA0, 0x9D, 0xEF, +0xF0, 0x90, 0xA2, 0x16, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0x3A, 0xE0, 0x64, 0x15, 0x70, 0x58, 0x90, +0xFD, 0x62, 0xE0, 0xFF, 0x30, 0xE6, 0x11, 0xF4, 0x54, 0x3F, 0x04, 0xFE, 0x51, 0x92, 0xC3, 0x9E, +0x51, 0x8A, 0x40, 0x12, 0xE4, 0xF0, 0x80, 0x0E, 0x51, 0x92, 0xFE, 0xEF, 0x54, 0x3F, 0x2E, 0x51, +0x8A, 0x40, 0x03, 0x74, 0x3F, 0xF0, 0x90, 0xA1, 0x39, 0xE0, 0xFF, 0x54, 0x30, 0xC4, 0x54, 0x0F, +0xFE, 0xEF, 0x25, 0xE0, 0x25, 0xE0, 0x4E, 0x90, 0xA1, 0x37, 0xF0, 0xE0, 0xFD, 0x7F, 0x2E, 0x12, +0x46, 0xA0, 0x90, 0xA1, 0x39, 0xE0, 0xC4, 0x54, 0xF0, 0xFF, 0x90, 0xA0, 0x9D, 0xE0, 0x54, 0x0F, +0x4F, 0xFD, 0x7F, 0x2D, 0x12, 0x46, 0xA0, 0x90, 0xA1, 0x3A, 0xE0, 0xB4, 0x21, 0x0D, 0x90, 0xFD, +0x62, 0xE0, 0xFF, 0x12, 0x9A, 0x48, 0x7F, 0x04, 0x12, 0x6F, 0x57, 0x90, 0xA1, 0x3A, 0xE0, 0xB4, +0x23, 0x04, 0x7F, 0x01, 0x31, 0xFA, 0x90, 0xA1, 0x3A, 0xE0, 0xB4, 0x27, 0x04, 0x7F, 0x02, 0x31, +0xFA, 0x90, 0xA1, 0x3A, 0xE0, 0xB4, 0x30, 0x0D, 0xE4, 0xFB, 0xFD, 0x7F, 0x01, 0x12, 0x99, 0x49, +0x7F, 0x04, 0x12, 0x6F, 0x57, 0x90, 0xA1, 0x3A, 0xE0, 0x64, 0x34, 0x60, 0x02, 0x21, 0x98, 0x90, +0xFD, 0x62, 0xE0, 0x30, 0xE0, 0x59, 0x90, 0xA0, 0x84, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, 0x02, +0x21, 0x98, 0x90, 0xA0, 0x62, 0x12, 0x4F, 0xD3, 0x30, 0xE0, 0x18, 0x12, 0x47, 0xF0, 0x90, 0xA0, +0x85, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x47, 0xF0, 0xE4, 0xFF, 0xFE, 0xEC, 0x12, 0x47, 0xD0, +0x12, 0x47, 0xD6, 0x51, 0x9B, 0x7D, 0x01, 0x12, 0x46, 0xB4, 0x90, 0xA1, 0x37, 0x74, 0x01, 0xF0, +0xFB, 0x7A, 0xA1, 0x79, 0x37, 0xFD, 0x7F, 0x34, 0x12, 0x6E, 0x00, 0x90, 0xA0, 0xA7, 0xE0, 0x44, +0x01, 0xF0, 0x90, 0x04, 0x9D, 0xE4, 0xF0, 0xE0, 0x44, 0x01, 0xF0, 0x51, 0xB3, 0x80, 0x39, 0x51, +0x9B, 0xE4, 0xFD, 0x12, 0x46, 0xB4, 0x90, 0xA0, 0x62, 0x12, 0x6F, 0xA4, 0x30, 0xE0, 0x1E, 0x12, +0x47, 0xF0, 0xE4, 0xFB, 0xFA, 0xED, 0xF9, 0xEC, 0xF8, 0x90, 0xA0, 0x85, 0xE0, 0xFE, 0xA3, 0xE0, +0xFF, 0xE4, 0xFC, 0xFD, 0x12, 0x45, 0x53, 0x12, 0x47, 0xD0, 0x12, 0x47, 0xD6, 0xD1, 0x2E, 0x90, +0x04, 0x9D, 0xE0, 0x54, 0xFE, 0xF0, 0x71, 0x02, 0x90, 0xA1, 0x3A, 0xE0, 0xFD, 0xB4, 0x35, 0x07, +0x90, 0xA0, 0x66, 0xE0, 0x44, 0x01, 0xF0, 0xED, 0xB4, 0x36, 0x23, 0x90, 0xFD, 0x61, 0xE0, 0x90, +0xA1, 0x37, 0xF0, 0x90, 0xFD, 0x62, 0xE0, 0x90, 0xA1, 0x38, 0xF0, 0x90, 0xA1, 0x3A, 0xE0, 0xFF, +0x90, 0xA1, 0x37, 0xE0, 0xFD, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x38, 0x12, 0x6E, 0x00, 0x90, 0xA1, +0x3A, 0xE0, 0xB4, 0x37, 0x02, 0x71, 0x29, 0x90, 0xA1, 0x3A, 0xE0, 0xB4, 0x40, 0x14, 0x90, 0xFD, +0x62, 0xE0, 0x30, 0xE0, 0x08, 0x90, 0xA0, 0x82, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0xA0, +0x82, 0xF0, 0x90, 0xFD, 0x68, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x51, 0x01, 0x7F, 0x04, 0x02, 0x6F, +0x57, 0x90, 0xA1, 0x98, 0x74, 0x09, 0xF0, 0x90, 0xA1, 0xA6, 0x74, 0x07, 0xF0, 0x90, 0xA1, 0x9A, +0xEF, 0xF0, 0x70, 0x31, 0x90, 0xA0, 0x78, 0xE0, 0x60, 0x1A, 0xA3, 0xE0, 0x60, 0x02, 0x80, 0x0C, +0x90, 0x07, 0x70, 0xE0, 0x70, 0x06, 0x90, 0x07, 0x74, 0xE0, 0x60, 0x08, 0x90, 0xA1, 0x9B, 0x74, +0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0xA1, 0x9B, 0xF0, 0xE4, 0x90, 0xA1, 0x9C, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0xA3, 0x80, 0x39, 0x90, 0xFD, 0x62, 0xE0, 0x90, 0xA1, 0x9B, 0xF0, 0x90, 0xFD, 0x63, +0xE0, 0x90, 0xA1, 0x9C, 0xF0, 0x90, 0xFD, 0x64, 0xE0, 0x90, 0xA1, 0x9D, 0xF0, 0x90, 0xFD, 0x65, +0xE0, 0x90, 0xA1, 0x9E, 0xF0, 0x90, 0xFD, 0x66, 0xE0, 0x90, 0xA1, 0x9F, 0xF0, 0x90, 0xFD, 0x67, +0xE0, 0x90, 0xA1, 0xA0, 0xF0, 0x90, 0xA1, 0x9B, 0xE0, 0x54, 0x01, 0x90, 0xA0, 0x78, 0xF0, 0xA3, +0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x98, 0x02, 0x6E, 0xA2, 0x90, 0xA1, 0x39, 0xF0, 0xD3, 0x94, +0x3F, 0x22, 0x90, 0xA0, 0x9C, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x90, 0xA0, 0x62, 0xE0, 0xC4, +0x13, 0x13, 0x54, 0x01, 0xFF, 0x90, 0xA0, 0xA1, 0xE0, 0xFB, 0x90, 0xA0, 0xA0, 0xE0, 0x90, 0xA1, +0xF7, 0xF0, 0x22, 0x90, 0x01, 0xE7, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x54, 0x01, +0xF1, 0x75, 0x54, 0xFD, 0x4F, 0xF0, 0xE0, 0xC3, 0x13, 0xFF, 0x54, 0x01, 0x90, 0x01, 0xE6, 0xF0, +0xA3, 0xE0, 0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE0, 0x27, 0x12, 0xAB, 0x37, 0x70, 0x20, 0x90, 0xA0, +0xA7, 0xE0, 0x30, 0xE0, 0x02, 0x80, 0x19, 0x90, 0xFD, 0x62, 0xE0, 0xB4, 0xAD, 0x0E, 0xA3, 0xE0, +0xB4, 0x35, 0x09, 0x51, 0xB3, 0x90, 0x01, 0xE5, 0x74, 0xDF, 0xF0, 0x22, 0x80, 0x00, 0x80, 0x02, +0x80, 0xB1, 0x90, 0x01, 0xE7, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0xA0, 0x87, 0xE0, 0x44, 0x04, +0xF0, 0x7D, 0x01, 0x7F, 0x23, 0x12, 0x6E, 0x00, 0x8F, 0x51, 0xE5, 0x51, 0xB4, 0x03, 0x09, 0xE4, +0xFF, 0x51, 0x01, 0x7F, 0x04, 0x12, 0x98, 0x0D, 0x22, 0x90, 0xA0, 0x62, 0x12, 0x4F, 0xD3, 0x20, +0xE0, 0x1D, 0x90, 0xFD, 0x62, 0xE0, 0x30, 0xE0, 0x16, 0xE0, 0x90, 0xA1, 0x3B, 0x30, 0xE1, 0x05, +0x74, 0x01, 0xF0, 0x80, 0x03, 0x74, 0x02, 0xF0, 0x90, 0xA1, 0x3B, 0xE0, 0xFF, 0x71, 0x50, 0x22, +0x90, 0xA1, 0x3C, 0xEF, 0xF0, 0x90, 0xA0, 0xA1, 0xE0, 0x70, 0x4D, 0x12, 0x47, 0xF0, 0xEE, 0x54, +0x0F, 0xFE, 0xE4, 0xFD, 0xFC, 0x90, 0xA1, 0x3D, 0x12, 0x08, 0x6D, 0xE4, 0x7F, 0x80, 0x91, 0x1F, +0x70, 0x05, 0x90, 0xA0, 0x80, 0x80, 0x1B, 0xE4, 0xFF, 0xFE, 0x91, 0x21, 0x70, 0x0A, 0x90, 0xA0, +0x80, 0x04, 0xF0, 0xE4, 0xA3, 0xF0, 0x80, 0x55, 0xE4, 0xFF, 0x91, 0x1F, 0x70, 0x09, 0x90, 0xA0, +0x80, 0x04, 0xF0, 0xA3, 0xF0, 0x80, 0x46, 0xE4, 0x7F, 0x80, 0xFE, 0x91, 0x21, 0x70, 0x3E, 0x90, +0xA0, 0x80, 0xF0, 0xA3, 0x04, 0xF0, 0x80, 0x35, 0x7F, 0x2C, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0xEF, +0x54, 0x02, 0x91, 0x34, 0x4E, 0x4F, 0x60, 0x08, 0x90, 0xA0, 0x80, 0x74, 0x01, 0xF0, 0x80, 0x05, +0xE4, 0x90, 0xA0, 0x80, 0xF0, 0xF1, 0x6E, 0xEF, 0x54, 0x01, 0x91, 0x34, 0x4E, 0x4F, 0x60, 0x07, +0xE4, 0x90, 0xA0, 0x81, 0xF0, 0x80, 0x06, 0x90, 0xA0, 0x81, 0x74, 0x01, 0xF0, 0x90, 0xA0, 0x7A, +0xE0, 0x44, 0x01, 0xF0, 0x7D, 0x11, 0x12, 0x63, 0x00, 0x90, 0x07, 0x78, 0xE0, 0x90, 0xA0, 0x7F, +0xF0, 0xF1, 0x7D, 0x12, 0x63, 0x84, 0x90, 0xA1, 0x3C, 0xE0, 0xFD, 0x70, 0x02, 0x80, 0x1C, 0xED, +0xB4, 0x01, 0x06, 0x91, 0x2D, 0x44, 0x20, 0xF0, 0x22, 0x90, 0xA1, 0x3C, 0xE0, 0xFD, 0xB4, 0x02, +0x06, 0x91, 0x2D, 0x44, 0x60, 0xF0, 0x22, 0xED, 0xB4, 0x03, 0x03, 0x91, 0x2D, 0xF0, 0x22, 0x7E, +0x02, 0xFD, 0xFC, 0x90, 0xA1, 0x3D, 0x12, 0x45, 0x8D, 0xC3, 0x02, 0x45, 0x60, 0x90, 0xA0, 0x7A, +0xE0, 0x54, 0x1F, 0x22, 0xFF, 0xE4, 0xFE, 0xFD, 0xFC, 0x90, 0xA1, 0x3D, 0x12, 0x08, 0x6D, 0x90, +0xA1, 0x3D, 0x12, 0x45, 0x71, 0xEC, 0x4D, 0x22, 0x12, 0xA5, 0x55, 0x7F, 0x08, 0x12, 0x47, 0xAF, +0xEF, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x46, 0xA0, 0xE4, 0xFF, 0x91, 0xE0, 0x51, 0x9B, 0xE4, +0xFD, 0x12, 0x46, 0xB4, 0x90, 0x9F, 0xA3, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x02, 0xF1, +0xAD, 0x90, 0x9F, 0xA4, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x91, 0x89, 0x91, 0x48, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x9F, 0xA4, 0xE0, 0x44, 0x10, 0xF0, +0x51, 0x9B, 0x7D, 0x01, 0x12, 0x46, 0xB4, 0x90, 0x9F, 0xB2, 0xE0, 0xFD, 0x7F, 0x93, 0x12, 0x46, +0xA0, 0x90, 0x9F, 0xA8, 0xE0, 0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, 0x10, +0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0, 0x7F, 0x08, 0x12, 0x47, 0xAF, 0xEF, 0x44, +0x10, 0xFD, 0x7F, 0x08, 0x12, 0x46, 0xA0, 0x7F, 0x01, 0x91, 0xE0, 0x7F, 0x90, 0x12, 0x47, 0xAF, +0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12, 0x46, 0xA0, 0x7F, 0x14, 0x7E, 0x00, 0x02, 0x3E, 0x50, +0x90, 0xA2, 0x23, 0xD1, 0x81, 0x90, 0x01, 0x09, 0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, +0x90, 0xA2, 0x23, 0xE0, 0x6F, 0x60, 0x34, 0xC3, 0x90, 0xA2, 0x25, 0xE0, 0x94, 0x88, 0x90, 0xA2, +0x24, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90, 0xA2, +0x24, 0xD1, 0x39, 0xD1, 0xD9, 0xD3, 0x90, 0xA2, 0x25, 0xE0, 0x94, 0x32, 0x90, 0xA2, 0x24, 0xE0, +0x94, 0x00, 0x40, 0xC1, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0, 0xBA, 0x22, 0x90, 0x9F, 0xAA, 0xE0, +0xFF, 0x60, 0x03, 0xB4, 0x08, 0x08, 0x12, 0xA9, 0x79, 0xBF, 0x01, 0x02, 0x91, 0x79, 0x22, 0x90, +0x9F, 0xA3, 0xE0, 0x30, 0xE0, 0x18, 0x90, 0x9F, 0x9E, 0xE0, 0xFF, 0x30, 0xE0, 0x0E, 0xC3, 0x13, +0x30, 0xE0, 0x07, 0xF1, 0xA0, 0xBF, 0x01, 0x06, 0x80, 0x02, 0x80, 0x00, 0xB1, 0x2C, 0x22, 0x90, +0xA0, 0x7A, 0xE0, 0x30, 0xE0, 0x05, 0x12, 0x9C, 0x28, 0x80, 0x03, 0x12, 0x9B, 0xEC, 0x90, 0xA0, +0xA7, 0xE0, 0x30, 0xE0, 0x04, 0xA3, 0xE0, 0x04, 0xF0, 0x90, 0xA0, 0xA8, 0xE0, 0x64, 0x08, 0x70, +0x17, 0x90, 0xA0, 0xA7, 0xE0, 0x30, 0xE0, 0x0B, 0x51, 0x9B, 0xE4, 0xFD, 0x12, 0x46, 0xB4, 0xD1, +0x2E, 0x80, 0x05, 0xE4, 0x90, 0xA0, 0xA8, 0xF0, 0x90, 0xA0, 0x63, 0x12, 0x6F, 0xA4, 0x30, 0xE0, +0x13, 0x90, 0xA0, 0xA9, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x14, 0x09, 0x90, 0x04, 0x9C, 0xE4, 0xF0, +0x90, 0xA0, 0xA9, 0xF0, 0x90, 0x9F, 0x9E, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x9F, 0xA0, 0x74, 0x01, +0xF0, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x4E, 0x90, 0x9F, 0xA3, 0xE0, 0x30, 0xE0, 0x1A, 0x90, 0x9F, +0xBE, 0xE0, 0x04, 0x12, 0x87, 0xC3, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, +0x90, 0x9F, 0xDE, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x9F, 0xA4, 0xE0, 0x13, 0x13, 0x13, 0x54, +0x1F, 0x30, 0xE0, 0x0A, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x03, 0x12, 0x5F, 0xA1, 0x90, 0xA2, +0x35, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, +0xF0, 0xE0, 0x44, 0x01, 0xF0, 0x7F, 0x01, 0x12, 0x6F, 0x57, 0x90, 0xA0, 0x52, 0xE0, 0x30, 0xE0, +0x0C, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x05, 0x12, 0x5F, 0xA1, 0xF1, 0x85, 0x22, 0x90, 0xA0, +0xA7, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x08, 0xD6, +0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA1, 0xF8, 0xEE, 0xF0, 0xA3, 0xD1, 0x81, 0x90, +0xA1, 0xF8, 0xF1, 0x97, 0xE0, 0x60, 0x23, 0xC3, 0x90, 0xA1, 0xFB, 0xE0, 0x94, 0xE8, 0x90, 0xA1, +0xFA, 0xE0, 0x94, 0x03, 0x40, 0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x00, 0x80, +0x0B, 0x90, 0xA1, 0xFA, 0xD1, 0x39, 0xD1, 0xF9, 0x80, 0xD5, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xE4, 0x90, 0xA0, 0xF1, 0xF0, 0xA3, 0xF0, +0xD1, 0xE0, 0xEF, 0x64, 0x01, 0x60, 0x3B, 0xC3, 0x90, 0xA0, 0xF2, 0xE0, 0x94, 0x88, 0x90, 0xA0, +0xF1, 0xE0, 0x94, 0x13, 0x40, 0x0F, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x01, 0xC7, +0x74, 0xFD, 0xF0, 0x80, 0x1D, 0x90, 0xA0, 0xF1, 0xD1, 0x39, 0xD1, 0xD9, 0xD3, 0x90, 0xA0, 0xF2, +0xE0, 0x94, 0x32, 0x90, 0xA0, 0xF1, 0xE0, 0x94, 0x00, 0x40, 0xC5, 0x90, 0x01, 0xC6, 0xE0, 0x30, +0xE3, 0xBE, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22, 0x7F, 0x14, 0x7E, 0x00, 0x02, 0x3E, 0x50, +0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x44, 0x0B, 0xD1, 0xF8, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xC0, +0x7F, 0x00, 0xB4, 0x40, 0x02, 0x7F, 0x01, 0x22, 0xF0, 0x7F, 0x0A, 0x7E, 0x00, 0x02, 0x3E, 0x50, +0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x00, 0x12, 0x45, 0xBE, 0x7F, 0x96, 0x7E, +0x02, 0xD1, 0x40, 0xEF, 0x60, 0x53, 0x90, 0x01, 0x17, 0xE0, 0xFE, 0x90, 0x01, 0x16, 0xE0, 0x7C, +0x00, 0x24, 0x00, 0xFF, 0xEC, 0x3E, 0xFE, 0xEF, 0x24, 0x01, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0xA2, +0x03, 0xEF, 0xF0, 0xEE, 0xFF, 0x90, 0xFD, 0x11, 0xF0, 0x90, 0xA2, 0x03, 0xE0, 0xFD, 0x90, 0x02, +0x94, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA2, 0x00, 0xF1, 0x8E, 0x24, 0x02, 0xFF, 0xE4, 0x33, 0xFE, +0x12, 0xA0, 0x27, 0x90, 0xA2, 0x03, 0xE0, 0x24, 0x18, 0xFF, 0x90, 0xA2, 0x00, 0x12, 0x45, 0xB5, +0x12, 0xA0, 0x80, 0x90, 0x02, 0x96, 0x74, 0x01, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x30, +0x7E, 0x09, 0x02, 0x37, 0x4E, 0x25, 0xE0, 0xFF, 0x90, 0xA0, 0x84, 0xE0, 0x22, 0x90, 0xA0, 0xA0, +0xE0, 0xFF, 0xE4, 0xFD, 0x22, 0x90, 0xA0, 0x54, 0xE0, 0x90, 0x05, 0x73, 0xF0, 0x22, 0x12, 0x45, +0xB5, 0x90, 0x00, 0x0E, 0x02, 0x06, 0xA2, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0x22, +0x90, 0x9F, 0xA1, 0xE0, 0x64, 0x02, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x90, 0xA0, 0x5B, +0xE0, 0x90, 0x01, 0x30, 0xF0, 0x90, 0xA0, 0x58, 0xE0, 0x90, 0x01, 0x39, 0xF0, 0x90, 0xA0, 0x59, +0xE0, 0x90, 0x01, 0x3A, 0xF0, 0x22, 0x90, 0xA0, 0x91, 0xE0, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x16, +0xEF, 0xB4, 0x01, 0x05, 0x90, 0xA0, 0x98, 0x80, 0x03, 0x90, 0xA0, 0x94, 0x12, 0x47, 0xCE, 0x7F, +0x80, 0x7E, 0x08, 0x12, 0x38, 0x45, 0x22, 0xE4, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0xAA, 0x12, 0x6F, +0x85, 0xB4, 0x02, 0x18, 0x90, 0xA2, 0x14, 0xE0, 0x64, 0x04, 0x60, 0x0B, 0x7F, 0x40, 0x11, 0x0D, +0x90, 0xA2, 0x14, 0xE0, 0x04, 0xF0, 0x22, 0xE4, 0x90, 0xA2, 0x14, 0xF0, 0x22, 0x90, 0xA2, 0x33, +0xEF, 0xF0, 0x7F, 0x02, 0x12, 0x44, 0xB7, 0x90, 0x9E, 0x92, 0xE0, 0xFF, 0x90, 0xA2, 0x33, 0xE0, +0xFE, 0xEF, 0x4E, 0x90, 0x9E, 0x92, 0xF0, 0x22, 0x90, 0xA1, 0x61, 0xEB, 0xF0, 0x70, 0x5D, 0x90, +0xA1, 0x61, 0xE0, 0xFE, 0x11, 0x8D, 0xE0, 0xFC, 0x90, 0xA1, 0x62, 0xE0, 0xFB, 0xEC, 0x6B, 0x60, +0x4B, 0x90, 0xA1, 0x66, 0xEB, 0xF0, 0xA3, 0xEE, 0xF0, 0xAE, 0x05, 0xEE, 0x25, 0xE0, 0x4F, 0xFF, +0x90, 0x9E, 0x91, 0xE0, 0xFE, 0x25, 0xE0, 0x25, 0xE0, 0x4F, 0x90, 0xA1, 0x68, 0xF0, 0x90, 0xA1, +0x63, 0xE0, 0x90, 0xA1, 0x6A, 0xF0, 0x90, 0xA1, 0x64, 0x74, 0x0C, 0xF0, 0x90, 0xA1, 0x72, 0x74, +0x04, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x64, 0x12, 0x6E, 0xA2, 0x7F, 0x04, 0x11, 0x0D, 0x90, +0xA1, 0x62, 0xE0, 0xFF, 0x90, 0xA1, 0x61, 0xE0, 0x11, 0x8D, 0xEF, 0xF0, 0x22, 0x24, 0x11, 0xF5, +0x82, 0xE4, 0x34, 0x99, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x06, +0x89, 0x90, 0xA1, 0x01, 0x12, 0x6A, 0x86, 0x90, 0xA1, 0x02, 0x12, 0x56, 0xDD, 0x90, 0xA1, 0x03, +0xF0, 0x12, 0x57, 0x09, 0x90, 0xA1, 0x04, 0x12, 0x6D, 0x27, 0x90, 0xA1, 0x05, 0x12, 0x96, 0x82, +0x90, 0xA0, 0x87, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0xA1, 0x02, 0xE0, 0xB4, 0x0C, 0x06, 0xE5, 0x70, +0x70, 0x11, 0x80, 0x00, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x01, 0x7D, 0x07, 0x7F, 0x30, 0x12, 0x6E, +0x00, 0x8F, 0x51, 0x90, 0xA1, 0x02, 0xE0, 0xB4, 0x0D, 0x0E, 0xE5, 0x51, 0x64, 0x01, 0x60, 0x05, +0x75, 0x70, 0x01, 0x80, 0x03, 0xE4, 0xF5, 0x70, 0xE5, 0x51, 0xB4, 0x01, 0x05, 0x75, 0x52, 0x01, +0x80, 0x03, 0xE4, 0xF5, 0x52, 0x90, 0xA1, 0x01, 0xE0, 0xFB, 0xAD, 0x52, 0xE4, 0xFF, 0x31, 0x49, +0x7F, 0x04, 0x11, 0x0D, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0xA1, 0x0C, 0x74, 0x12, 0xF0, 0x90, +0xA1, 0x1A, 0x74, 0x05, 0xF0, 0x90, 0xA1, 0x0E, 0xEF, 0x12, 0x4F, 0xBF, 0x90, 0xA1, 0x0A, 0xE0, +0x90, 0xA1, 0x11, 0xF0, 0x90, 0xA1, 0x0B, 0xE0, 0x90, 0xA1, 0x12, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, +0x79, 0x0C, 0x12, 0x6E, 0xA2, 0x7F, 0x04, 0x01, 0x0D, 0x90, 0xA1, 0xA7, 0x74, 0x0B, 0xF0, 0x90, +0xA1, 0xB5, 0x74, 0x07, 0xF0, 0x90, 0xA1, 0xA9, 0xEF, 0xF0, 0x60, 0x32, 0x90, 0xFD, 0x63, 0xE0, +0x90, 0xA1, 0xAA, 0xF0, 0x90, 0xFD, 0x61, 0xE0, 0x90, 0xA1, 0xAB, 0xF0, 0x90, 0xFD, 0x64, 0xE0, +0x90, 0xA1, 0xAC, 0xF0, 0x90, 0xFD, 0x65, 0xE0, 0x90, 0xA1, 0xAD, 0xF0, 0x90, 0xFD, 0x66, 0xE0, +0x90, 0xA1, 0xAE, 0xF0, 0x90, 0xFD, 0x67, 0xE0, 0x90, 0xA1, 0xAF, 0xF0, 0x80, 0x0D, 0x90, 0xA1, +0xAA, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0xE4, 0xA3, 0x12, 0x58, 0xA4, 0x7B, 0x01, 0x7A, 0xA1, 0x79, +0xA7, 0x02, 0x6E, 0xA2, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x01, 0x7F, 0xF5, 0x7E, 0x01, 0x12, 0x34, +0xC1, 0xBF, 0x01, 0x06, 0x90, 0xA1, 0x01, 0xE0, 0xA3, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x01, +0x7F, 0xF6, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0xA1, 0x01, 0xE0, 0x90, 0xA1, +0x03, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x01, 0x7F, 0xF4, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, +0x01, 0x08, 0x90, 0xA1, 0x01, 0xE0, 0x90, 0xA1, 0x04, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x01, +0x7F, 0xF3, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0xA1, 0x01, 0xE0, 0x90, 0xA1, +0x05, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x01, 0x7F, 0xF2, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, +0x01, 0x08, 0x90, 0xA1, 0x01, 0xE0, 0x90, 0xA1, 0x06, 0xF0, 0x90, 0xA1, 0x02, 0xE0, 0xFF, 0xA3, +0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0xA1, 0x0A, 0xF0, 0x90, 0xA1, 0x06, 0xE0, 0x90, +0xA1, 0x0B, 0xF0, 0x21, 0x19, 0x12, 0x06, 0x89, 0xFF, 0x90, 0x9F, 0x8B, 0xF0, 0xBF, 0x01, 0x07, +0x31, 0xA4, 0xE4, 0x90, 0x9F, 0x8B, 0xF0, 0x22, 0x90, 0xA1, 0x3B, 0x74, 0x08, 0xF0, 0x90, 0xA1, +0x49, 0x74, 0x01, 0xF0, 0x90, 0xA1, 0x3D, 0xEF, 0xF0, 0x7B, 0x01, 0x7A, 0xA1, 0x79, 0x3B, 0x02, +0x6E, 0xA2, 0x90, 0xA1, 0x2B, 0xEF, 0xF0, 0x90, 0xA1, 0x2D, 0x74, 0x02, 0xF0, 0x7F, 0x01, 0x12, +0x8A, 0x84, 0x90, 0xA0, 0x63, 0x12, 0x8D, 0x05, 0x30, 0xE0, 0x22, 0x90, 0xA1, 0x2B, 0xE0, 0xB4, +0x02, 0x04, 0x7D, 0x07, 0x80, 0x09, 0x90, 0xA1, 0x2B, 0xE0, 0xB4, 0x05, 0x07, 0x7D, 0x0D, 0x7F, +0xFF, 0x12, 0x49, 0x22, 0x12, 0x4C, 0x22, 0xBF, 0x01, 0x03, 0x12, 0x63, 0x05, 0x90, 0xA0, 0x63, +0x12, 0x56, 0xE4, 0x30, 0xE0, 0x04, 0x7F, 0x03, 0x80, 0x02, 0x7F, 0x01, 0x12, 0x62, 0xC3, 0x90, +0xA1, 0x2B, 0xE0, 0xB4, 0x02, 0x0D, 0x90, 0xA0, 0x60, 0xE0, 0x24, 0x03, 0xFF, 0x90, 0xA0, 0x6F, +0x12, 0x66, 0xE8, 0x90, 0xA0, 0x5F, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0xE4, 0x90, 0xA1, 0x2C, +0xF0, 0x80, 0x06, 0x90, 0xA1, 0x2C, 0x74, 0x01, 0xF0, 0x71, 0xCD, 0x20, 0xE0, 0x13, 0x90, 0xA0, +0xA0, 0xE0, 0x60, 0x08, 0x90, 0xA1, 0x2D, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0xA1, 0x2D, +0xF0, 0x90, 0xA1, 0x2D, 0xE0, 0xFF, 0x90, 0xA1, 0x2C, 0xE0, 0xFD, 0x12, 0x63, 0x84, 0xE4, 0x90, +0xA0, 0x71, 0xF0, 0x90, 0xA1, 0x2B, 0xE0, 0xFF, 0xB4, 0x02, 0x05, 0x12, 0x67, 0x9C, 0x80, 0x09, +0xEF, 0xB4, 0x05, 0x05, 0xE4, 0x90, 0xA0, 0x72, 0xF0, 0x71, 0xC4, 0x30, 0xE0, 0x17, 0x90, 0xA1, +0x2B, 0xE0, 0xB4, 0x02, 0x04, 0x7D, 0x08, 0x80, 0x4B, 0x90, 0xA1, 0x2B, 0xE0, 0x64, 0x05, 0x70, +0x48, 0x7D, 0x0E, 0x80, 0x3F, 0x71, 0xB3, 0x30, 0xE0, 0x1E, 0x71, 0xBB, 0x20, 0xE0, 0x02, 0x71, +0xA9, 0x90, 0xA1, 0x2B, 0xE0, 0xB4, 0x02, 0x04, 0x7D, 0x09, 0x80, 0x28, 0x90, 0xA1, 0x2B, 0xE0, +0x64, 0x05, 0x70, 0x25, 0x7D, 0x0F, 0x80, 0x1C, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x1B, 0x71, 0xA9, +0x90, 0xA1, 0x2B, 0xE0, 0xB4, 0x02, 0x04, 0x7D, 0x0A, 0x80, 0x09, 0x90, 0xA1, 0x2B, 0xE0, 0xB4, +0x05, 0x07, 0x7D, 0x10, 0x7F, 0x6F, 0x12, 0x49, 0x22, 0x90, 0xA0, 0x62, 0xE0, 0x30, 0xE0, 0x03, +0x12, 0x5C, 0x93, 0x90, 0xA0, 0x62, 0x12, 0x56, 0xE4, 0x30, 0xE0, 0x05, 0xE4, 0xFF, 0x12, 0x97, +0xC6, 0x90, 0xA0, 0x63, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x0E, 0x90, 0x06, 0xCD, 0xE0, 0x54, 0xEF, +0xF0, 0x90, 0x06, 0xCF, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x9F, 0xA9, 0xE0, 0xFF, 0xE4, 0xFD, +0x02, 0x5A, 0xA1, 0x90, 0xA0, 0x5F, 0xE0, 0xC4, 0x54, 0x0F, 0x22, 0x90, 0xA0, 0x63, 0xE0, 0xC4, +0x13, 0x54, 0x07, 0x22, 0x90, 0xA0, 0x5F, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x22, 0x90, 0xA0, 0x62, +0xE0, 0xC4, 0x13, 0x54, 0x07, 0x22, 0x7E, 0x00, 0x7F, 0x0A, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0xA0, +0x79, 0x87, 0x12, 0x08, 0xAA, 0x90, 0xA0, 0x73, 0x74, 0x02, 0xF0, 0x22, 0xE4, 0xFF, 0x90, 0xA0, +0x5F, 0xE0, 0x30, 0xE0, 0x32, 0xA3, 0x12, 0x66, 0xE8, 0x90, 0xA0, 0x72, 0x74, 0x01, 0xF0, 0x90, +0xA0, 0x71, 0xF0, 0x90, 0xA0, 0x51, 0xE0, 0x60, 0x07, 0x7D, 0x05, 0x7F, 0x6F, 0x02, 0x49, 0x22, +0x12, 0x5C, 0x93, 0x90, 0xA0, 0x5F, 0x12, 0x8F, 0xB4, 0x20, 0xE0, 0x0B, 0xEF, 0x13, 0x13, 0x54, +0x3F, 0x30, 0xE0, 0x03, 0x12, 0x6F, 0xDF, 0x22, 0x12, 0x67, 0xA3, 0x90, 0xA0, 0x7A, 0x12, 0x8F, +0xB4, 0xFE, 0xEF, 0xC3, 0x13, 0x54, 0x0F, 0xC3, 0x9E, 0x40, 0x03, 0x02, 0x67, 0xB3, 0x90, 0xA0, +0x7A, 0xE0, 0xFF, 0xC3, 0x13, 0x54, 0x0F, 0xFE, 0xEF, 0x54, 0xE1, 0xFF, 0xEE, 0x04, 0x54, 0x0F, +0x25, 0xE0, 0x4F, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x7F, 0xC2, 0x12, +0x06, 0x89, 0xFF, 0x90, 0x9F, 0x9D, 0xF0, 0xBF, 0x01, 0x09, 0x12, 0x6A, 0x87, 0x64, 0x01, 0x60, +0x1D, 0x80, 0x18, 0x12, 0x57, 0xE3, 0x12, 0x6A, 0x87, 0x64, 0x01, 0x60, 0x11, 0x90, 0x9F, 0x9E, +0xE0, 0x20, 0xE0, 0x07, 0xE4, 0xFF, 0x12, 0x84, 0x59, 0x80, 0x03, 0x12, 0x82, 0xFC, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0x90, 0x04, 0x24, 0x91, 0xAD, 0x90, 0xA0, 0xD0, 0x12, 0x6A, 0x86, 0x25, 0x51, +0x90, 0xA0, 0xDE, 0x12, 0x56, 0xDD, 0x25, 0x51, 0x90, 0xA0, 0xEC, 0xF0, 0x22, 0xE0, 0xF5, 0x51, +0x12, 0x06, 0x89, 0x25, 0x51, 0x22, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFF, 0x90, 0xA0, 0xEF, 0xE0, +0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12, 0x56, 0xDE, 0xFF, 0x30, 0xE0, 0x1F, 0x12, 0x06, 0x89, 0x90, +0xA0, 0x4B, 0x12, 0x6A, 0x86, 0x90, 0xA0, 0x4C, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0xA3, 0xE0, 0x54, +0x01, 0x4F, 0xF0, 0x12, 0x57, 0x09, 0x90, 0xA0, 0x4E, 0xF0, 0x22, 0x91, 0xF1, 0x74, 0x05, 0xF0, +0x22, 0x90, 0xA0, 0x4B, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, +0x1E, 0xF0, 0xA3, 0x22, 0x12, 0x06, 0x89, 0x90, 0x9F, 0xB2, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x90, +0xA0, 0x51, 0xF0, 0x60, 0x29, 0x90, 0xA0, 0x5F, 0xE0, 0x20, 0xE0, 0x22, 0xE4, 0xFD, 0x7F, 0x04, +0x12, 0x5A, 0xA1, 0xB1, 0x3F, 0x30, 0xE0, 0x16, 0x12, 0x86, 0xD3, 0x20, 0xE0, 0x10, 0xB1, 0x48, +0x54, 0x3F, 0x30, 0xE0, 0x04, 0x7F, 0x0D, 0x80, 0x02, 0x7F, 0x09, 0x12, 0x62, 0xC3, 0x22, 0x90, +0xA0, 0x50, 0xE0, 0xFF, 0xC3, 0x13, 0x22, 0xF0, 0x90, 0xA0, 0x50, 0xE0, 0x13, 0x13, 0x22, 0x12, +0x8F, 0xC9, 0x90, 0xA0, 0x56, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0xEF, 0x54, 0x02, 0xB1, 0x71, 0x90, +0x9F, 0xA3, 0xE0, 0x54, 0xEF, 0x4F, 0xF0, 0x90, 0xA0, 0x56, 0xE0, 0x54, 0x01, 0xFF, 0x02, 0x58, +0xD3, 0x33, 0x33, 0x33, 0x54, 0xF8, 0xFF, 0x22, 0x12, 0x06, 0x89, 0x54, 0x01, 0xB1, 0x71, 0x90, +0xA0, 0x84, 0xE0, 0x54, 0xF7, 0x4F, 0xF0, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x90, 0x07, 0x65, +0x30, 0xE0, 0x04, 0x74, 0x18, 0xF0, 0x22, 0xE4, 0xF0, 0x22, 0x90, 0xA2, 0x17, 0x12, 0x45, 0xBE, +0xE4, 0xFE, 0x90, 0xFD, 0x50, 0xEF, 0xF0, 0x64, 0x30, 0x60, 0x1E, 0xA3, 0xED, 0xF0, 0xEE, 0xC3, +0x9D, 0x50, 0x09, 0xB1, 0xEC, 0xB1, 0xE1, 0xEF, 0xF0, 0x0E, 0x80, 0xF2, 0xEE, 0xC3, 0x94, 0x06, +0x50, 0x18, 0xB1, 0xE1, 0xE4, 0xF0, 0x0E, 0x80, 0xF3, 0xEE, 0xC3, 0x94, 0x07, 0x50, 0x0B, 0xB1, +0xEC, 0x74, 0x51, 0xB1, 0xE3, 0xEF, 0xF0, 0x0E, 0x80, 0xEF, 0x90, 0xFD, 0x58, 0x74, 0x01, 0xF0, +0x22, 0x74, 0x52, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFD, 0xF5, 0x83, 0x22, 0x90, 0xA2, 0x17, 0x12, +0x45, 0xB5, 0x8E, 0x82, 0x75, 0x83, 0x00, 0x12, 0x06, 0xA2, 0xFF, 0x22, 0x90, 0xA0, 0x87, 0xE0, +0x44, 0x10, 0xF0, 0x7D, 0x01, 0x7F, 0x1B, 0x12, 0x6E, 0x00, 0x90, 0xA1, 0x01, 0xEF, 0xF0, 0x22, +0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA0, 0x88, 0xE0, 0x44, 0x01, 0xF0, 0x7D, 0x01, +0x7F, 0x28, 0xD1, 0x07, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x6F, 0x66, 0x90, 0xA2, 0x1A, 0xE0, +0x70, 0x08, 0xD1, 0x7A, 0x90, 0xA2, 0x1A, 0x74, 0x01, 0xF0, 0x12, 0x6A, 0x73, 0x12, 0x06, 0x89, +0xFF, 0xE4, 0x8F, 0x54, 0xF5, 0x53, 0xF5, 0x52, 0xF5, 0x51, 0x90, 0xA0, 0x98, 0x12, 0x45, 0x71, +0xEC, 0x54, 0xC1, 0xFC, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xAF, 0x54, 0xAE, 0x53, +0xAD, 0x52, 0xAC, 0x51, 0x78, 0x19, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, +0x00, 0x12, 0x45, 0x53, 0x90, 0xA0, 0x94, 0x02, 0x08, 0x6D, 0x7F, 0x80, 0x7E, 0x08, 0x12, 0x37, +0x4E, 0x90, 0xA0, 0x98, 0x02, 0x08, 0x6D, 0x12, 0x06, 0x89, 0x90, 0xA0, 0xA0, 0x12, 0x6A, 0x86, +0x90, 0xA0, 0xA1, 0xF0, 0x22, 0x12, 0x8F, 0xC9, 0x90, 0xA0, 0xAD, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, +0xF0, 0xEF, 0x54, 0x06, 0xFF, 0xEE, 0x54, 0xF9, 0x4F, 0xFF, 0xF0, 0x12, 0x06, 0x89, 0xFE, 0x54, +0x08, 0xFD, 0xEF, 0x54, 0xF7, 0x4D, 0xFF, 0x90, 0xA0, 0xAD, 0x12, 0x6F, 0xAC, 0xF1, 0x79, 0x4E, +0x90, 0xA0, 0xAD, 0x12, 0x6A, 0x86, 0xFF, 0x54, 0x03, 0xFE, 0x90, 0xA0, 0xAE, 0xE0, 0x54, 0xFC, +0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x04, 0xFF, 0xEE, 0x54, 0xFB, 0x4F, 0xFF, 0x12, 0x6A, 0x86, 0xFE, +0x54, 0x30, 0xFD, 0xEF, 0x54, 0xCF, 0x4D, 0xFF, 0x90, 0xA0, 0xAE, 0x12, 0x6F, 0x3B, 0x4E, 0x12, +0x56, 0xDD, 0x90, 0xA0, 0xAF, 0xF0, 0x12, 0x57, 0x09, 0x90, 0xA0, 0xB0, 0x12, 0x6D, 0x27, 0x90, +0xA0, 0xB1, 0xF0, 0x90, 0xA0, 0xAF, 0xF1, 0x6C, 0xEF, 0x78, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, +0xD8, 0xF9, 0xFF, 0x90, 0xA0, 0xB7, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA0, 0xB0, 0xF1, 0x6C, +0xEF, 0x78, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0xA0, 0xB9, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0x90, 0xA0, 0xB1, 0xF1, 0x6C, 0x90, 0xA0, 0xBB, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, +0x90, 0xA0, 0xAD, 0xE0, 0x30, 0xE0, 0x14, 0x90, 0xA0, 0xB2, 0x74, 0x01, 0xF0, 0xA3, 0xF0, 0xA3, +0x12, 0x96, 0x82, 0x90, 0x07, 0x83, 0xE0, 0x44, 0x20, 0xF0, 0x22, 0xE4, 0x90, 0xA0, 0xB2, 0x12, +0x58, 0xA4, 0xA3, 0xF0, 0x90, 0x07, 0x83, 0xE0, 0x54, 0xDF, 0xF0, 0x22, 0xE0, 0xFF, 0x7E, 0x00, +0x7C, 0x01, 0x7D, 0x40, 0x02, 0x07, 0x03, 0xF0, 0xEE, 0x54, 0x20, 0xFE, 0xEF, 0x54, 0xDF, 0x22, +0x12, 0x06, 0x89, 0x54, 0x01, 0x25, 0xE0, 0x12, 0x97, 0x75, 0x54, 0xFB, 0x4F, 0xF0, 0xE0, 0x13, +0x13, 0x54, 0x3F, 0x30, 0xE0, 0x02, 0x80, 0x12, 0x90, 0xA0, 0xA7, 0xE0, 0x20, 0xE0, 0x02, 0xF1, +0xA2, 0x22, 0x90, 0x07, 0x65, 0xE0, 0x54, 0xE7, 0xF0, 0x22, 0x90, 0x07, 0x65, 0xE0, 0x44, 0x18, +0xF0, 0x22, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFF, 0x90, 0xA0, 0xBF, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, +0x30, 0xE0, 0x55, 0x90, 0x00, 0x40, 0xE0, 0x54, 0xBF, 0x44, 0xA0, 0xFD, 0x7F, 0x40, 0x12, 0x46, +0xA0, 0x90, 0x00, 0x41, 0xE0, 0x44, 0x04, 0xFD, 0x7F, 0x41, 0x12, 0x46, 0xA0, 0x90, 0x00, 0x6A, +0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x6A, 0x12, 0x46, 0xA0, 0x90, 0x07, 0x6E, 0x74, 0x55, 0xF0, 0xA3, +0x74, 0x12, 0xF0, 0x90, 0x07, 0x78, 0xE0, 0x54, 0xF2, 0x44, 0x02, 0xF0, 0x90, 0x06, 0xCC, 0xE0, +0x44, 0x03, 0xF0, 0x90, 0x07, 0x65, 0xE0, 0x54, 0xF5, 0xF0, 0x90, 0x05, 0x23, 0xE0, 0x54, 0x7F, +0xF0, 0xE4, 0xFD, 0x7F, 0x66, 0x12, 0x46, 0xA0, 0x22, 0xE4, 0x90, 0x9F, 0x87, 0xF0, 0xA3, 0xF0, +0x90, 0x9E, 0xEF, 0xF0, 0xA3, 0xF0, 0x22, 0xE4, 0xFC, 0xED, 0x2C, 0x24, 0x00, 0x11, 0x78, 0xE4, +0xF0, 0x0C, 0xEC, 0xB4, 0x18, 0xF3, 0x74, 0x00, 0x2D, 0x11, 0x78, 0xEF, 0xF0, 0xEE, 0x54, 0x3F, +0xFF, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x02, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0, 0x74, 0x03, 0x2D, 0xF5, 0x82, +0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x74, 0x0B, 0x2D, 0xF5, 0x82, 0xE4, 0x34, +0xFB, 0xF5, 0x83, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x22, +0x90, 0xA1, 0xFC, 0xEF, 0xF0, 0xA3, 0x12, 0x45, 0xBE, 0x90, 0xA2, 0x1C, 0xE0, 0xFE, 0x04, 0xF0, +0x90, 0x00, 0x01, 0xEE, 0x12, 0x06, 0xE1, 0x74, 0x00, 0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, +0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0xA1, 0xFD, 0x12, 0x45, 0xB5, 0x8B, 0x40, 0x8A, +0x41, 0x89, 0x42, 0x75, 0x43, 0x02, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, +0xA1, 0xFC, 0xE0, 0x24, 0x02, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, +0xC0, 0x01, 0xA3, 0x12, 0x45, 0xB5, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0x8B, 0x40, 0xF5, 0x41, +0x89, 0x42, 0x90, 0xA1, 0xFD, 0x12, 0x97, 0x8E, 0xF5, 0x43, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, +0x02, 0x35, 0x26, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0x90, 0x9F, 0x88, 0xE0, +0xFE, 0x90, 0x9F, 0x87, 0xE0, 0xFD, 0xB5, 0x06, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, +0x64, 0x01, 0x60, 0x40, 0xED, 0x31, 0x59, 0xFA, 0x7B, 0x01, 0x12, 0x97, 0x00, 0x7F, 0x01, 0xEF, +0x60, 0x32, 0x90, 0x9F, 0x87, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x02, 0x80, 0x02, 0x7F, 0x00, +0xEF, 0x60, 0x05, 0xE4, 0x90, 0x9F, 0x87, 0xF0, 0x90, 0x9F, 0x88, 0xE0, 0xFF, 0x90, 0x9F, 0x87, +0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x07, 0x90, 0x9E, 0x92, +0xE0, 0x44, 0x04, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0xF0, 0x0F, 0xA4, 0x24, 0xF1, 0xF9, +0x74, 0x9E, 0x35, 0xF0, 0x22, 0x90, 0xA2, 0x1D, 0x12, 0x45, 0xBE, 0xE4, 0xFF, 0x90, 0xA2, 0x1D, +0x12, 0x45, 0xB5, 0x8F, 0x82, 0x75, 0x83, 0x00, 0x12, 0x06, 0xA2, 0xFE, 0x74, 0xF0, 0x2F, 0x31, +0x89, 0xEE, 0xF0, 0x0F, 0xEF, 0xB4, 0x10, 0xE5, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, +0x22, 0x90, 0x00, 0xF1, 0xE0, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF, 0x22, 0x75, 0x15, 0x12, 0xE4, +0xF5, 0x16, 0x75, 0x17, 0x07, 0x75, 0x18, 0x32, 0x90, 0x01, 0x30, 0xE5, 0x15, 0xF0, 0xA3, 0xE5, +0x16, 0xF0, 0xA3, 0xE5, 0x17, 0xF0, 0xA3, 0xE5, 0x18, 0xF0, 0x22, 0x75, 0x1D, 0x06, 0x75, 0x1E, +0x01, 0x75, 0x1F, 0x03, 0x75, 0x20, 0x62, 0x43, 0x20, 0x80, 0x43, 0x1F, 0x04, 0x90, 0x01, 0x38, +0xE5, 0x1D, 0xF0, 0xA3, 0xE5, 0x1E, 0xF0, 0xA3, 0xE5, 0x1F, 0xF0, 0xA3, 0xE5, 0x20, 0xF0, 0x22, +0x90, 0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x22, 0x7D, 0x02, 0x90, +0x01, 0xC4, 0x74, 0xED, 0xF0, 0x74, 0xA1, 0xA3, 0xF0, 0x90, 0xA0, 0xC0, 0xE0, 0xFF, 0xED, 0xC3, +0x9F, 0x50, 0x10, 0xED, 0x25, 0xE0, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x03, 0x7F, 0x00, 0x22, +0x0D, 0x80, 0xE6, 0x74, 0xED, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xA1, 0xA3, 0xF0, 0x7F, 0x01, +0x22, 0xE4, 0x90, 0x9E, 0x92, 0x12, 0x58, 0xA4, 0xA3, 0xF0, 0x22, 0x90, 0x01, 0xE4, 0x74, 0x1F, +0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x34, 0xE0, 0x55, 0x15, 0xF5, 0x19, 0xA3, 0xE0, 0x55, +0x16, 0xF5, 0x1A, 0xA3, 0xE0, 0x55, 0x17, 0xF5, 0x1B, 0xA3, 0xE0, 0x55, 0x18, 0xF5, 0x1C, 0x90, +0x01, 0x34, 0xE5, 0x19, 0xF0, 0xA3, 0xE5, 0x1A, 0xF0, 0xA3, 0xE5, 0x1B, 0xF0, 0xA3, 0xE5, 0x1C, +0xF0, 0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x1D, 0xF5, 0x21, 0xA3, 0xE0, 0x55, 0x1E, 0xF5, 0x22, +0xA3, 0xE0, 0x55, 0x1F, 0xF5, 0x23, 0xA3, 0xE0, 0x55, 0x20, 0xF5, 0x24, 0x90, 0x01, 0x3C, 0xE5, +0x21, 0xF0, 0xA3, 0xE5, 0x22, 0xF0, 0xA3, 0xE5, 0x23, 0xF0, 0xA3, 0xE5, 0x24, 0xF0, 0x53, 0x91, +0xDF, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90, 0xA1, 0x1B, 0xF0, 0xE0, 0xFF, 0x30, 0xE0, 0x07, 0x90, +0x01, 0xCF, 0xE0, 0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE5, 0x23, 0x90, 0x01, 0xCF, 0xE0, 0x54, 0xDF, +0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0xE4, 0xF5, 0xA8, 0xF5, 0xE8, 0x12, 0x58, 0x7E, 0x90, +0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x46, 0xA0, 0x80, 0xFE, 0x22, 0x90, 0x9F, +0x9E, 0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x9F, 0x9E, 0xE0, 0xFF, +0x30, 0xE0, 0x04, 0x51, 0xFD, 0x60, 0x15, 0x90, 0x9F, 0xA7, 0xE0, 0x70, 0x04, 0xEF, 0x30, 0xE0, +0x0B, 0x90, 0x9F, 0xAA, 0xE0, 0x64, 0x02, 0x60, 0x03, 0x12, 0x86, 0xFF, 0x22, 0x90, 0x9F, 0xA2, +0xE0, 0x64, 0x02, 0x22, 0x12, 0x6F, 0xA1, 0x30, 0xE0, 0x0B, 0x51, 0xFD, 0x60, 0x07, 0x7D, 0x01, +0x7F, 0x02, 0x12, 0x5A, 0xA1, 0x51, 0xFD, 0x60, 0x02, 0x71, 0x1C, 0x22, 0x90, 0x9F, 0xA7, 0xE0, +0x64, 0x02, 0x60, 0x10, 0x12, 0x69, 0x3A, 0x60, 0x0B, 0x71, 0x35, 0xEF, 0x70, 0x06, 0xFD, 0x7F, +0x0C, 0x12, 0x5A, 0xA1, 0x22, 0x90, 0x04, 0x1A, 0xE0, 0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, +0x04, 0x1B, 0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x71, 0x35, +0xEF, 0x70, 0x03, 0x12, 0x5E, 0x6F, 0x22, 0x90, 0x9F, 0x9E, 0xE0, 0xFF, 0x30, 0xE0, 0x3E, 0x90, +0x9F, 0xA2, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02, 0x7E, 0x01, 0x90, 0x9F, 0xA1, 0xE0, 0x7D, 0x00, +0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70, 0x24, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x03, 0x02, +0x82, 0xFC, 0x71, 0x04, 0x90, 0x9F, 0xA2, 0xE0, 0xB4, 0x08, 0x06, 0xE4, 0xFD, 0x7F, 0x0C, 0x80, +0x09, 0x90, 0x9F, 0xA2, 0xE0, 0x70, 0x06, 0xFD, 0x7F, 0x04, 0x12, 0x5A, 0xA1, 0x22, 0x90, 0xA0, +0x5F, 0xE0, 0x30, 0xE0, 0x17, 0x90, 0xA0, 0x71, 0xE0, 0x70, 0x5F, 0x90, 0x9F, 0xA9, 0xE0, 0xD3, +0x94, 0x00, 0x50, 0x56, 0x90, 0xA0, 0x51, 0xE0, 0x60, 0x4D, 0x80, 0x4E, 0x71, 0x35, 0xEF, 0x64, +0x01, 0x70, 0x47, 0x90, 0x9F, 0xAB, 0xE0, 0xFF, 0x54, 0x03, 0x70, 0x3E, 0x90, 0x9F, 0xA9, 0xE0, +0xFE, 0xE4, 0xC3, 0x9E, 0x40, 0x34, 0xEF, 0x20, 0xE2, 0x30, 0x90, 0x9F, 0xAB, 0xE0, 0x20, 0xE4, +0x29, 0x90, 0x9F, 0xA4, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x1E, 0x90, 0xA0, 0x51, 0xE0, +0x70, 0x18, 0x90, 0x06, 0x62, 0xE0, 0x20, 0xE1, 0x11, 0x90, 0x06, 0x62, 0xE0, 0x30, 0xE0, 0x07, +0xE0, 0x54, 0xFC, 0x64, 0x80, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xE4, 0xFF, 0x12, +0x5F, 0x2F, 0xBF, 0x01, 0x13, 0x90, 0x9F, 0xA7, 0xE0, 0x60, 0x0D, 0x12, 0x69, 0x3A, 0x64, 0x02, +0x60, 0x03, 0x02, 0x6F, 0xDF, 0x12, 0x5F, 0xB7, 0x22, 0x90, 0x9F, 0x9E, 0xE0, 0xFF, 0x30, 0xE0, +0x40, 0x90, 0x9F, 0xA2, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02, 0x7E, 0x01, 0x90, 0x9F, 0xA1, 0xE0, +0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70, 0x26, 0xEF, 0xC3, 0x13, 0x30, 0xE0, +0x03, 0x02, 0x82, 0xFC, 0x12, 0x8E, 0xDF, 0x90, 0x9F, 0xA2, 0xE0, 0xB4, 0x0C, 0x06, 0xE4, 0xFD, +0x7F, 0x08, 0x80, 0x0A, 0x90, 0x9F, 0xA2, 0xE0, 0xB4, 0x04, 0x06, 0xE4, 0xFD, 0xFF, 0x12, 0x5A, +0xA1, 0x22, 0x90, 0x9F, 0xA3, 0xE0, 0xFF, 0x12, 0x56, 0xE5, 0x30, 0xE0, 0x1B, 0xEF, 0x54, 0x7F, +0xB1, 0x05, 0x30, 0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFD, 0xF0, 0x90, +0x9F, 0xA7, 0xE0, 0x60, 0x03, 0x12, 0x68, 0x44, 0x90, 0xA0, 0x63, 0x12, 0x6F, 0xA4, 0x30, 0xE0, +0x22, 0x90, 0xA0, 0x66, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, 0x18, 0xEF, 0x54, 0xFD, 0xF0, 0x90, +0x04, 0xE0, 0xE0, 0x90, 0xA0, 0x66, 0x30, 0xE1, 0x06, 0xE0, 0x44, 0x04, 0xF0, 0x80, 0x04, 0xE0, +0x54, 0xFB, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x30, 0xE1, 0x02, 0x91, 0xCD, 0x22, 0x90, 0xA0, 0xC1, +0xE0, 0x30, 0xE0, 0x22, 0x91, 0xF7, 0xE0, 0xFE, 0x30, 0xE0, 0x1B, 0x75, 0xF0, 0x0E, 0xEF, 0x91, +0xFF, 0xEE, 0x54, 0xFE, 0xF0, 0x90, 0xA0, 0xC3, 0x74, 0x05, 0xF0, 0x12, 0x4A, 0x4C, 0x54, 0x07, +0xFD, 0x7F, 0x01, 0x12, 0x49, 0xA5, 0x22, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0x75, 0xF0, 0x0E, 0x90, +0xA0, 0xCC, 0x02, 0x45, 0xA9, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x9F, 0xA4, 0x22, 0xE4, 0x90, +0xA1, 0x2C, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x7F, 0x83, 0x12, 0x47, 0xAF, 0x90, 0xA1, 0x2C, 0xEF, +0xF0, 0x7F, 0x83, 0x12, 0x47, 0xAF, 0xAE, 0x07, 0x90, 0xA1, 0x2C, 0xE0, 0xFF, 0xB5, 0x06, 0x01, +0x22, 0xC3, 0x90, 0xA1, 0x2E, 0xE0, 0x94, 0x64, 0x90, 0xA1, 0x2D, 0xE0, 0x94, 0x00, 0x40, 0x0D, +0x90, 0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0xA1, 0x2C, 0xE0, 0xFF, 0x22, 0x90, 0xA1, 0x2D, +0x12, 0x96, 0x39, 0x80, 0xC2, 0x90, 0x01, 0xC4, 0x74, 0x55, 0xF0, 0x74, 0xA5, 0xA3, 0xF0, 0x7F, +0x90, 0x12, 0x47, 0xAF, 0xEF, 0x20, 0xE0, 0xF7, 0x74, 0x55, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, +0xA5, 0xA3, 0xF0, 0x22, 0xE4, 0xF5, 0x5E, 0xB1, 0xA8, 0xE0, 0xFE, 0xB4, 0x02, 0x08, 0xED, 0xC3, +0x94, 0x11, 0x40, 0x21, 0x80, 0x17, 0xEE, 0xB4, 0x01, 0x08, 0xED, 0xC3, 0x94, 0x0A, 0x40, 0x15, +0x80, 0x0B, 0xB1, 0xA8, 0xE0, 0x70, 0x0B, 0xED, 0xC3, 0x94, 0x03, 0x40, 0x08, 0x75, 0x5E, 0x01, +0x80, 0x03, 0xE4, 0xF5, 0x5E, 0xAF, 0x5E, 0x22, 0x74, 0x91, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x95, +0xF5, 0x83, 0x22, 0x8F, 0x52, 0x8D, 0x53, 0x8B, 0x54, 0x75, 0xF0, 0x04, 0xEF, 0x12, 0x51, 0x19, +0xC4, 0x54, 0x03, 0x90, 0xA1, 0x06, 0xF0, 0x90, 0xA1, 0x04, 0x60, 0x09, 0x74, 0x32, 0xF0, 0xA3, +0x74, 0x2F, 0xF0, 0x80, 0x07, 0x74, 0x11, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0xE5, 0x53, 0xD3, 0x94, +0x2D, 0x40, 0x0A, 0x75, 0xF0, 0x04, 0xE5, 0x52, 0x12, 0x57, 0xEF, 0x80, 0x20, 0xE5, 0x53, 0xD3, +0x94, 0x1E, 0x40, 0x05, 0x90, 0xA1, 0x04, 0x80, 0x14, 0xE5, 0x53, 0xD3, 0x94, 0x14, 0x40, 0x05, +0x90, 0xA1, 0x05, 0x80, 0x08, 0x75, 0xF0, 0x04, 0xE5, 0x52, 0x12, 0x56, 0xF1, 0xE0, 0xFD, 0x85, +0x54, 0x6A, 0xE4, 0xFB, 0xAF, 0x52, 0x02, 0x77, 0x89, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0xA1, 0x74, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0xA1, 0x73, 0xEF, 0xF0, 0xA3, 0xA3, 0xE0, +0xFD, 0x12, 0x3E, 0x02, 0x90, 0xA1, 0x7E, 0x12, 0x08, 0x6D, 0x90, 0xA1, 0x76, 0x12, 0x45, 0x71, +0x12, 0x08, 0x3A, 0x90, 0xA1, 0x7E, 0x12, 0x4F, 0xF0, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, +0x07, 0x90, 0xA1, 0x76, 0x12, 0x45, 0x71, 0x90, 0xA1, 0x7A, 0x12, 0x4F, 0xF0, 0xD0, 0x03, 0xD0, +0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x45, 0x53, 0x90, 0xA1, 0x82, 0x12, 0x08, 0x6D, 0x90, 0xA1, +0x74, 0xA3, 0xE0, 0xFD, 0xC0, 0x05, 0x90, 0xA1, 0x82, 0x12, 0x45, 0x71, 0x90, 0xAA, 0x96, 0x12, +0x08, 0x6D, 0x90, 0xA1, 0x73, 0xE0, 0xFF, 0xD0, 0x05, 0x12, 0x3D, 0x09, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0xA2, 0x08, 0xEF, 0xF0, 0xED, 0x64, 0x01, +0x70, 0x2E, 0xEB, 0xB4, 0x01, 0x07, 0xE0, 0x24, 0x02, 0xF5, 0x72, 0x80, 0x08, 0x90, 0xA2, 0x08, +0xE0, 0x24, 0xFE, 0xF5, 0x72, 0x90, 0xA1, 0x76, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0xAF, +0x72, 0xF1, 0x02, 0xD1, 0xFA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0x72, 0x80, 0x1F, +0x90, 0xA1, 0x76, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0x90, 0xA2, 0x08, 0xE0, 0xFF, 0xF1, +0x02, 0xD1, 0xFA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0x90, 0xA2, 0x08, 0xE0, 0xFF, 0xF1, +0x02, 0x7F, 0x01, 0xD1, 0x19, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xFF, 0xD1, 0x19, 0x90, 0xA1, +0x76, 0x22, 0xE4, 0xFC, 0xFD, 0xFE, 0x90, 0xA1, 0x7A, 0x12, 0x08, 0x6D, 0x7D, 0x18, 0x7C, 0x00, +0x22, 0x7E, 0x00, 0x7F, 0x2D, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0xC1, 0x02, 0x08, 0xAA, +0xC3, 0xEF, 0x9D, 0xF5, 0x56, 0xC3, 0x94, 0x08, 0x50, 0x1C, 0xE4, 0xF5, 0x57, 0xF1, 0x87, 0xC0, +0x83, 0xC0, 0x82, 0x90, 0xA1, 0x05, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0x75, 0xF0, 0x03, 0x12, 0x45, +0xA9, 0xE5, 0x56, 0xF0, 0x80, 0x3E, 0xE5, 0x56, 0xC3, 0x94, 0x10, 0x50, 0x09, 0x75, 0x57, 0x01, +0xE5, 0x56, 0x24, 0xF8, 0x80, 0x17, 0xE5, 0x56, 0xC3, 0x94, 0x18, 0x50, 0x09, 0x75, 0x57, 0x02, +0xE5, 0x56, 0x24, 0xF0, 0x80, 0x07, 0x75, 0x57, 0x03, 0xE5, 0x56, 0x24, 0xE8, 0xFF, 0xF1, 0x87, +0xC0, 0x83, 0xC0, 0x82, 0x90, 0xA1, 0x05, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0x75, 0xF0, 0x03, 0x12, +0x45, 0xA9, 0xEF, 0xF0, 0xAF, 0x57, 0x22, 0x75, 0xF0, 0x0E, 0xEB, 0x90, 0xA0, 0xC8, 0x02, 0x45, +0xA9, 0xAF, 0x54, 0xF1, 0x20, 0x90, 0xA1, 0x01, 0xEF, 0xF0, 0x22, 0x8F, 0x54, 0x8D, 0x55, 0xAE, +0x03, 0x74, 0x1F, 0xC3, 0x95, 0x54, 0x40, 0x0B, 0x12, 0xA8, 0x01, 0xE4, 0xFD, 0xF1, 0x93, 0x24, +0xD4, 0x80, 0x34, 0x74, 0x3F, 0xC3, 0x95, 0x54, 0x40, 0x0B, 0x12, 0xA8, 0x01, 0x7D, 0x20, 0xF1, +0x91, 0x24, 0x88, 0x80, 0x22, 0x74, 0x5F, 0xC3, 0x95, 0x54, 0x40, 0x0B, 0x12, 0xA8, 0x01, 0x7D, +0x40, 0xF1, 0x91, 0x24, 0xD0, 0x80, 0x10, 0x74, 0x7F, 0xC3, 0x95, 0x54, 0x40, 0x22, 0x12, 0xA8, +0x01, 0x7D, 0x60, 0xF1, 0x91, 0x24, 0x84, 0xFD, 0xE4, 0x34, 0x04, 0xFC, 0x75, 0xF0, 0x0E, 0xE5, +0x55, 0x12, 0xA8, 0x0C, 0x75, 0xF0, 0x03, 0xEE, 0x12, 0x45, 0xA9, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, +0x22, 0x90, 0xA1, 0x05, 0xEE, 0xF0, 0xAB, 0x55, 0x22, 0x75, 0xF0, 0x0E, 0x90, 0xA0, 0xC6, 0x02, +0x45, 0xA9, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x37, 0x4E, +0x90, 0xA0, 0xF4, 0x12, 0x08, 0x6D, 0x7F, 0x00, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0x90, 0xA0, 0xF8, +0x12, 0x08, 0x6D, 0x90, 0xA0, 0xF4, 0x11, 0x7F, 0x60, 0x18, 0x90, 0xA0, 0xF4, 0x11, 0x76, 0x90, +0xA0, 0xF4, 0x12, 0x08, 0x6D, 0x90, 0xA0, 0xF4, 0x12, 0x47, 0xCE, 0x7F, 0x00, 0x7E, 0x08, 0x12, +0x38, 0x45, 0x90, 0xA0, 0xF8, 0x11, 0x7F, 0x60, 0x18, 0x90, 0xA0, 0xF8, 0x11, 0x76, 0x90, 0xA0, +0xF8, 0x12, 0x08, 0x6D, 0x90, 0xA0, 0xF8, 0x12, 0x47, 0xCE, 0x7F, 0x00, 0x7E, 0x09, 0x12, 0x38, +0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x45, 0x71, 0xEF, 0x54, 0xFE, 0xFF, 0xEC, 0x22, 0x12, +0x45, 0x71, 0xEF, 0x54, 0x01, 0xFF, 0xE4, 0xFE, 0xFD, 0xFC, 0xEF, 0x22, 0x7E, 0x00, 0x7F, 0x01, +0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x9F, 0x79, 0x9E, 0x12, 0x08, 0xAA, 0x90, 0x9F, 0x9E, 0xE0, 0x54, +0xFD, 0xF0, 0xE4, 0x12, 0x58, 0xA5, 0xA3, 0x74, 0x0C, 0xF0, 0x22, 0x7D, 0x22, 0x7F, 0xFF, 0x12, +0x49, 0x22, 0x12, 0x5F, 0xD6, 0x02, 0x85, 0x7F, 0x12, 0x5F, 0xD6, 0x7D, 0x23, 0x12, 0x63, 0x00, +0x02, 0x67, 0xE3, 0xAE, 0x07, 0x12, 0x82, 0xF0, 0xBF, 0x01, 0x13, 0x90, 0x9F, 0x9E, 0x12, 0x4F, +0xD3, 0x20, 0xE0, 0x0A, 0xAF, 0x06, 0x7D, 0x01, 0x12, 0x5A, 0xA1, 0x7F, 0x01, 0x22, 0x7F, 0x00, +0x22, 0x31, 0x1F, 0x54, 0x1F, 0x30, 0xE0, 0x05, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92, +0x74, 0x02, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0x31, 0x18, 0x90, 0xA0, 0x4D, 0xE0, 0xC3, 0x13, +0x54, 0x7F, 0x90, 0xA1, 0xDA, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x12, 0x48, 0x34, +0x90, 0x9F, 0xA3, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0xF0, 0xE4, 0x90, 0xA1, 0xD9, 0xF0, 0x22, 0x90, +0x9F, 0xA3, 0xE0, 0x13, 0x13, 0x13, 0x22, 0x90, 0x9F, 0xA3, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0x90, +0x9F, 0xB0, 0xF0, 0xA3, 0xF0, 0x90, 0x9F, 0xAB, 0xF0, 0x90, 0x9F, 0xA4, 0xE0, 0x54, 0xF7, 0xF0, +0x54, 0xBF, 0x12, 0x5C, 0xC6, 0x7D, 0x10, 0x7F, 0x03, 0x02, 0x88, 0xAD, 0xEF, 0x24, 0xFE, 0x60, +0x0B, 0x04, 0x70, 0x24, 0x90, 0x9F, 0xAD, 0x74, 0x02, 0xF0, 0x80, 0x13, 0xED, 0x70, 0x06, 0x90, +0xA0, 0x4E, 0xE0, 0x80, 0x02, 0xED, 0x14, 0x90, 0x9F, 0xAD, 0xF0, 0x90, 0x9F, 0xAD, 0xE0, 0xA3, +0xF0, 0x90, 0x9F, 0xA4, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0xA0, 0x52, 0xE0, 0xC3, 0x13, 0x20, +0xE0, 0x13, 0x90, 0x02, 0x87, 0xE0, 0x70, 0x17, 0x90, 0x02, 0x96, 0xE0, 0x70, 0x11, 0x90, 0x02, +0x86, 0xE0, 0x30, 0xE1, 0x0A, 0x90, 0xA0, 0xA7, 0xE0, 0x20, 0xE0, 0x03, 0x7F, 0x01, 0x22, 0x7F, +0x00, 0x22, 0x7D, 0x2E, 0x7F, 0x6F, 0x12, 0x49, 0x22, 0x7D, 0x02, 0x7F, 0x01, 0x12, 0x5A, 0x1E, +0x31, 0xB9, 0x90, 0x9F, 0xA2, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0, +0x22, 0x90, 0xA1, 0xE8, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x81, 0x00, 0xE0, 0x54, 0x0F, 0xFD, +0xAC, 0x07, 0x51, 0x32, 0xE0, 0x44, 0x01, 0xF0, 0x51, 0x32, 0xE0, 0x54, 0xFB, 0xF0, 0xAC, 0x07, +0x74, 0x12, 0x2C, 0x12, 0x4F, 0x9E, 0xE0, 0x44, 0xFA, 0xF0, 0x74, 0x11, 0x2C, 0x51, 0x3D, 0xE0, +0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, +0x44, 0x0E, 0xF0, 0x90, 0x04, 0xA7, 0xE4, 0xF0, 0x90, 0x04, 0xA6, 0xF0, 0x90, 0x04, 0xA5, 0x74, +0xFF, 0xF0, 0x90, 0x04, 0xA4, 0x74, 0xFD, 0xF0, 0x74, 0x14, 0x2C, 0x51, 0x2A, 0xE0, 0x54, 0xC0, +0x4D, 0xFD, 0x74, 0x14, 0x2F, 0x51, 0x2A, 0xED, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, +0x83, 0x22, 0x74, 0x0D, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, +0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90, 0xA1, 0xE6, 0xE0, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0xA2, 0x3B, 0xEF, 0xF0, 0x90, 0x9E, 0x9A, 0xE0, 0xFF, 0x90, 0x04, 0x1C, 0xE0, 0x6F, +0x70, 0x3E, 0x90, 0x9F, 0xAA, 0xE0, 0x64, 0x0E, 0x70, 0x15, 0x90, 0xA2, 0x3B, 0xE0, 0x70, 0x30, +0x90, 0x9F, 0xA3, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06, 0x04, 0x12, 0x5A, 0x16, 0x80, 0x1E, 0x90, +0x9F, 0xAA, 0xE0, 0x64, 0x06, 0x70, 0x19, 0x90, 0xA2, 0x3B, 0xE0, 0x60, 0x13, 0x90, 0x9F, 0xA3, +0xE0, 0x54, 0xBF, 0xF0, 0x51, 0xA5, 0xF0, 0x90, 0x9F, 0xAA, 0x74, 0x04, 0xF0, 0x12, 0x5C, 0x93, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x40, 0xF0, 0xE0, 0x44, 0x80, 0x22, +0x90, 0x9E, 0x9D, 0xE0, 0xFF, 0xE4, 0xFB, 0x7D, 0x01, 0x12, 0x4D, 0x59, 0x90, 0xA1, 0xED, 0xEE, +0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xA1, 0xEB, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0xAB, 0x07, 0x90, 0xA2, 0x3C, 0xED, 0xF0, 0xEC, 0xF9, 0xE0, 0xFF, 0xAE, 0x03, +0x74, 0x2A, 0x2E, 0x51, 0xEF, 0x12, 0x4F, 0x8F, 0xE9, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x22, 0xE4, 0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, +0x30, 0xE0, 0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED, 0xF0, 0xAF, 0x06, 0x22, 0xE5, 0x53, 0x25, +0xE0, 0x24, 0xC3, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x22, 0x90, 0x9E, 0x9B, 0xE0, 0xFF, +0x7B, 0x08, 0x7D, 0x01, 0x12, 0x4D, 0x59, 0x90, 0xA2, 0x11, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, +0xFD, 0x90, 0xA2, 0x10, 0xE0, 0xFF, 0x22, 0x7F, 0xA3, 0x12, 0x47, 0xAF, 0xEF, 0x54, 0xF8, 0x44, +0x05, 0xFD, 0x7F, 0xA3, 0x12, 0x46, 0xA0, 0x7F, 0xA0, 0x12, 0x47, 0xAF, 0xEF, 0x54, 0x0F, 0x64, +0x04, 0x22, 0x90, 0xA2, 0x36, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0xEF, 0x54, 0x03, 0xFF, 0xE4, +0x22, 0x74, 0x11, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9B, 0xF5, 0x83, 0x22, 0x12, 0x64, 0xAA, +0x12, 0x5F, 0x92, 0x90, 0x9F, 0xA3, 0xE0, 0x54, 0xF7, 0xF0, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, +0x22, 0x74, 0x91, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9C, 0xF5, 0x83, 0x22, 0x7F, 0x2C, 0x7E, +0x09, 0x12, 0x37, 0x4E, 0xEF, 0x54, 0xFC, 0xFF, 0x22, 0xFD, 0x7C, 0x00, 0x12, 0x07, 0x03, 0xEF, +0x25, 0x55, 0xF5, 0x55, 0xEE, 0x35, 0x54, 0xF5, 0x54, 0x22, 0xE4, 0xF0, 0xA3, 0xF0, 0x74, 0x91, +0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x98, 0xF5, 0x83, 0xE4, 0x22, 0xF0, 0x90, 0x9F, 0xDD, 0xE0, 0x24, +0x04, 0x90, 0x9F, 0xBF, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x22, 0xA4, 0xF5, 0x82, 0x85, 0xF0, 0x83, +0x12, 0x07, 0xAB, 0xAE, 0xF0, 0xA8, 0x59, 0x08, 0x22, 0xFD, 0x75, 0xF0, 0x0E, 0x90, 0xA0, 0xC4, +0x02, 0x45, 0xA9, 0x7E, 0x00, 0x7F, 0x04, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0xA0, 0x79, 0x52, 0x22, +0xD3, 0x9F, 0xEE, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x22, 0x90, 0x9F, 0xA4, 0xE0, 0x44, 0x04, +0xF0, 0x22, 0x12, 0x45, 0xA9, 0xE0, 0xFC, 0xA3, 0xE0, 0xF5, 0x82, 0x8C, 0x83, 0x22, 0x90, 0xA2, +0x04, 0xE0, 0x24, 0x11, 0xF5, 0x82, 0xE4, 0x34, 0x9E, 0x22, 0x74, 0x01, 0x25, 0x51, 0xF5, 0x82, +0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0x74, 0x91, 0x25, 0x51, 0xF5, 0x82, 0xE4, 0x34, 0x9A, 0xF5, +0x83, 0x22, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF0, 0x90, +0x9F, 0xB3, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0xFF, 0xEE, 0x54, 0x3F, 0x90, 0x9F, 0xE2, +0xF0, 0xA3, 0xEF, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x9B, 0xF5, 0x83, 0xE5, 0x5F, 0xF0, 0x22, 0x90, +0x00, 0x08, 0x02, 0x07, 0xAB, 0xFE, 0x54, 0x03, 0xFF, 0xEE, 0x13, 0x13, 0x54, 0x07, 0x22, 0x90, +0xA0, 0xC1, 0xE0, 0xFE, 0xC3, 0x13, 0x54, 0x07, 0x22, 0x90, 0xA2, 0x0F, 0xE0, 0xFF, 0x90, 0xA2, +0x0D, 0xE0, 0x22, 0xD3, 0xE5, 0x57, 0x94, 0xE8, 0xE5, 0x56, 0x94, 0x03, 0x22, 0xFF, 0xEE, 0x55, +0x83, 0xFE, 0xEF, 0x55, 0x82, 0x4E, 0x22, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0x75, 0xF0, 0x08, +0x22, 0x7F, 0x16, 0x12, 0x47, 0xAF, 0xEF, 0x54, 0x0F, 0x22, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x54, +0xF8, 0xF0, 0x22, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, 0x22, 0xE5, 0x6C, 0x75, 0xF0, +0x08, 0xA4, 0x25, 0x6B, 0x22, 0xFF, 0x90, 0xA2, 0x06, 0xE0, 0xFB, 0xEF, 0x5B, 0x22, 0x90, 0xA0, +0x65, 0xE0, 0x54, 0xDF, 0xF0, 0xE4, 0x22, 0x90, 0x9F, 0x9E, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x22, +0x90, 0xA1, 0xF7, 0xE0, 0x7F, 0x48, 0x7E, 0x09, 0x22, 0xFF, 0x12, 0x06, 0x89, 0x54, 0x0F, 0xFD, +0x22, 0xC4, 0x54, 0x0F, 0x90, 0xA2, 0x0B, 0xF0, 0x22, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x6B, 0x08, +0x22, 0xE5, 0x57, 0xAE, 0x56, 0xA8, 0x59, 0x08, 0x22, 0xE5, 0x54, 0xF0, 0xA3, 0xE5, 0x55, 0xF0, +0x22, 0x54, 0x03, 0x4F, 0xFF, 0x75, 0xF0, 0x10, 0x22, 0x90, 0xA0, 0xAD, 0xE0, 0x13, 0x13, 0x13, +0x22, 0x90, 0xA1, 0xC5, 0x12, 0x45, 0x71, 0xEF, 0x22, 0x12, 0x45, 0x71, 0xEF, 0x44, 0x80, 0xFF, +0x22, 0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0x22, 0x12, 0x47, 0xAF, 0xEF, 0x44, 0x40, 0xFD, +0x22, 0x00, 0x36, 0x6E }; -u4Byte ArrayLength_MP_8723B_FW_NIC = 27324; +u4Byte ArrayLength_MP_8723B_FW_NIC = 28004; @@ -3334,16 +3377,16 @@ ODM_ReadFirmware_MP_8723B_FW_NIC( *pFirmwareSize = ArrayLength_MP_8723B_FW_NIC; } -// v29 20140605 by Isaachsu +// v31.00 20140813 by Isaachsu u1Byte Array_MP_8723B_FW_WoWLAN[] = { -0x01, 0x53, 0x30, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x06, 0x05, 0x10, 0x59, 0x5A, 0x60, 0x00, 0x00, -0xF8, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x48, 0x94, 0x02, 0x67, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x68, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x68, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x53, 0x30, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x08, 0x13, 0x23, 0x38, 0xAA, 0x61, 0x00, 0x00, +0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x48, 0x94, 0x02, 0x70, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x70, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x70, 0x38, 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, 0x02, 0x68, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x77, 0xEF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x70, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x77, 0xFC, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x7F, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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, @@ -3483,1405 +3526,1426 @@ u1Byte Array_MP_8723B_FW_WoWLAN[] = { 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, -0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0x41, 0x95, 0x7B, 0x00, 0x41, 0x95, 0x7C, 0x00, 0x41, -0x95, 0x8E, 0x00, 0x41, 0x94, 0xD0, 0x00, 0x41, 0x94, 0xB2, 0x00, 0x44, 0x95, 0x6E, 0x00, 0x50, -0xF2, 0x01, 0x00, 0x4B, 0xF0, 0x58, 0x47, 0x60, 0x24, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, -0x8F, 0x82, 0x75, 0x83, 0x00, 0xED, 0xF0, 0x7F, 0x10, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x56, 0xEF, 0xF0, 0x90, -0x95, 0x58, 0xEB, 0xF0, 0xED, 0x60, 0x02, 0x41, 0x14, 0x90, 0x07, 0x6E, 0xE0, 0x44, 0x08, 0xF0, -0x90, 0x07, 0x65, 0xE0, 0x54, 0xE7, 0xF0, 0x90, 0x95, 0x58, 0xE0, 0x70, 0x4B, 0xF1, 0x49, 0x70, -0x41, 0x90, 0x95, 0x59, 0xE0, 0x7F, 0x48, 0x7E, 0x09, 0x70, 0x19, 0x12, 0x37, 0x4E, 0xE4, 0xFF, -0x74, 0x02, 0x71, 0x8F, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x7F, 0x64, 0x51, 0x84, 0xEF, -0x54, 0xFE, 0x80, 0x19, 0x12, 0x37, 0x4E, 0xE4, 0xFE, 0x74, 0x80, 0xFF, 0xE4, 0x71, 0x90, 0x7F, -0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x7F, 0x64, 0x51, 0x84, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x64, -0x31, 0x39, 0x7F, 0x4E, 0xF1, 0xD9, 0x41, 0x76, 0xF1, 0x49, 0x70, 0x0D, 0x12, 0x9F, 0x36, 0xFF, -0x71, 0x8F, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x7F, 0x4E, 0x51, 0x84, 0xEF, 0x54, 0x7F, -0xF1, 0x3E, 0x44, 0x01, 0xFD, 0x7F, 0x4F, 0x31, 0x39, 0x7F, 0x30, 0x12, 0x9F, 0x38, 0x74, 0x66, -0xFF, 0x71, 0x90, 0x7F, 0x30, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x7F, 0x2C, 0x7E, 0x09, 0x12, 0x37, -0x4E, 0xEF, 0x54, 0xFC, 0xFF, 0xEF, 0x44, 0x01, 0xFF, 0x71, 0x90, 0x7F, 0x2C, 0x7E, 0x09, 0x12, -0x38, 0x45, 0x80, 0x6B, 0x90, 0x07, 0x6E, 0xE0, 0x54, 0xF7, 0xF0, 0x90, 0x07, 0x65, 0xE0, 0x44, -0x18, 0xF0, 0x90, 0x95, 0x56, 0xE0, 0x70, 0x47, 0x90, 0x95, 0x58, 0xE0, 0x60, 0x12, 0x7F, 0x67, -0x51, 0x84, 0xEF, 0x44, 0x20, 0xFD, 0x7F, 0x67, 0x31, 0x39, 0x12, 0x9F, 0x36, 0xFF, 0x80, 0x26, -0x7F, 0x67, 0x51, 0x84, 0xEF, 0x54, 0xDF, 0xFD, 0x7F, 0x67, 0x31, 0x39, 0x90, 0x95, 0x59, 0xE0, -0x7F, 0x48, 0x7E, 0x09, 0x70, 0x0B, 0x12, 0x37, 0x4E, 0xE4, 0x74, 0x80, 0xFF, 0x74, 0x02, 0x80, -0x05, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0x71, 0x8F, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x7F, -0x4E, 0x51, 0x84, 0xEF, 0x54, 0x7F, 0xF1, 0x3E, 0x54, 0xFE, 0xFD, 0x7F, 0x4F, 0x31, 0x39, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x82, 0x75, 0x83, 0x00, -0xE0, 0x90, 0x95, 0x89, 0xF0, 0x7F, 0x10, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0x90, 0x95, 0x89, 0xE0, -0xFF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x84, -0xED, 0xF0, 0x90, 0x95, 0x83, 0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x42, 0x7F, 0x47, 0x71, 0x4D, -0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0xFD, 0x7F, 0x47, 0x31, 0x39, 0x7F, 0x46, 0x71, -0x4D, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0xFD, 0x7F, 0x46, 0x12, 0xA0, 0x47, 0x60, 0x0D, -0x7F, 0x45, 0x71, 0x4D, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0x80, 0x0C, 0x7F, 0x45, 0x71, -0x4D, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0xFD, 0x7F, 0x45, 0x80, 0x46, 0x90, 0x95, -0x83, 0xE0, 0x24, 0xF8, 0xF0, 0x7F, 0x63, 0x71, 0x4D, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, -0x5F, 0xFD, 0x7F, 0x63, 0x31, 0x39, 0x7F, 0x62, 0x71, 0x4D, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, -0x4F, 0xFD, 0x7F, 0x62, 0x12, 0xA0, 0x47, 0x60, 0x0E, 0x71, 0x4B, 0x80, 0x02, 0xC3, 0x33, 0xD8, -0xFC, 0x4F, 0xFD, 0x7F, 0x61, 0x80, 0x0D, 0x71, 0x4B, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, -0x5F, 0xFD, 0x7F, 0x61, 0x31, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x61, 0x51, 0x84, 0x90, -0x95, 0x83, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, -0xD0, 0x12, 0x9E, 0xC4, 0x7D, 0x01, 0x31, 0x53, 0x12, 0x57, 0xFC, 0x71, 0xAA, 0x71, 0x97, 0x71, -0x97, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x31, 0x39, 0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0, 0xA3, 0xE0, -0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xFE, -0xEC, 0x90, 0xAA, 0xB9, 0x02, 0x08, 0x6D, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x31, 0x39, 0x7F, 0x02, -0x51, 0x84, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x02, 0x31, 0x39, 0x7F, 0x02, 0x51, 0x84, 0xEF, 0x22, -0x7F, 0x54, 0x51, 0x84, 0xE5, 0x0D, 0x5F, 0xF5, 0x11, 0x7F, 0x55, 0x51, 0x84, 0xE5, 0x0E, 0x5F, -0xF5, 0x12, 0x7F, 0x56, 0x51, 0x84, 0xE5, 0x0F, 0x5F, 0xF5, 0x13, 0x7F, 0x57, 0x51, 0x84, 0xE5, -0x10, 0x5F, 0xF5, 0x14, 0xAD, 0x11, 0x7F, 0x54, 0x31, 0x39, 0xAD, 0x12, 0x7F, 0x55, 0x31, 0x39, -0xAD, 0x13, 0x7F, 0x56, 0x31, 0x39, 0xAD, 0x14, 0x7F, 0x57, 0x31, 0x39, 0x53, 0x91, 0xEF, 0x22, -0x7F, 0x81, 0x51, 0x84, 0xEF, 0x54, 0xFE, 0xFD, 0x7F, 0x81, 0x31, 0x39, 0x7F, 0x80, 0xF1, 0xD9, -0xFD, 0x7F, 0x80, 0x31, 0x39, 0x12, 0x91, 0xB5, 0x12, 0x3E, 0x11, 0xF1, 0xFA, 0x12, 0x91, 0xF2, -0x7F, 0x01, 0x12, 0x47, 0x00, 0x90, 0x93, 0x88, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x47, 0x00, 0x90, -0x93, 0x88, 0xE0, 0x04, 0xF0, 0x91, 0x55, 0x12, 0x8A, 0x53, 0x7F, 0x80, 0xF1, 0xFB, 0x7F, 0x80, -0x31, 0x39, 0x75, 0x28, 0xFF, 0x12, 0x60, 0x1D, 0x12, 0x91, 0xC2, 0x12, 0x93, 0x18, 0x7F, 0x81, -0x51, 0x84, 0xEF, 0x44, 0x04, 0xFD, 0x7F, 0x81, 0x31, 0x39, 0x12, 0x91, 0xFC, 0x12, 0x93, 0x43, -0xE4, 0xFF, 0x02, 0x47, 0x89, 0x12, 0x60, 0x03, 0x90, 0x8D, 0x06, 0xEF, 0xF0, 0x12, 0x91, 0x6B, -0x90, 0x01, 0x64, 0x74, 0x01, 0xF0, 0x90, 0x04, 0x23, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x17, 0x51, -0x84, 0xEF, 0x54, 0xFC, 0x44, 0x04, 0xFD, 0x7F, 0x17, 0x31, 0x39, 0x7F, 0x16, 0x51, 0x84, 0xEF, -0x54, 0x0F, 0x44, 0x40, 0xFD, 0x7F, 0x16, 0x31, 0x39, 0x7F, 0x38, 0xF1, 0xFB, 0x7F, 0x38, 0x31, -0x39, 0x02, 0x37, 0x99, 0xAD, 0x07, 0x90, 0x8F, 0x33, 0xE0, 0x75, 0xF0, 0x40, 0xA4, 0xFF, 0x90, -0x95, 0x6A, 0xE5, 0xF0, 0x12, 0x67, 0xF4, 0x90, 0x8F, 0x34, 0xE0, 0xC3, 0x13, 0x54, 0x7F, 0x90, -0x95, 0x6D, 0xF0, 0xED, 0x64, 0x01, 0x70, 0x70, 0x90, 0x95, 0x6A, 0xE0, 0x70, 0x02, 0xA3, 0xE0, -0x60, 0x0B, 0x90, 0x95, 0x6A, 0x74, 0xFF, 0x75, 0xF0, 0xD0, 0x12, 0x08, 0xD6, 0xB1, 0x34, 0x13, -0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x51, 0xA6, 0xB1, 0x34, 0x13, 0x54, 0x01, -0xFD, 0x51, 0xA6, 0x90, 0x8F, 0x34, 0xE0, 0x30, 0xE0, 0x3E, 0xB1, 0x29, 0x13, 0x54, 0x07, 0x7D, -0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x51, 0xA6, 0xE4, 0x90, 0x95, 0x6C, 0xF0, 0x90, 0x95, 0x6D, -0xE0, 0xFF, 0x90, 0x95, 0x6C, 0xE0, 0xC3, 0x9F, 0x50, 0x1E, 0xB1, 0x29, 0x13, 0x54, 0x01, 0xFD, -0x51, 0xA6, 0xB1, 0x29, 0x13, 0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x51, 0xA6, -0x90, 0x95, 0x6C, 0xE0, 0x04, 0xF0, 0x80, 0xD5, 0x22, 0x90, 0x95, 0x6A, 0xE0, 0xFE, 0xA3, 0xE0, -0xFF, 0x12, 0x3E, 0x50, 0x90, 0x8F, 0x32, 0xE0, 0x54, 0x7F, 0xFF, 0x90, 0x8F, 0x31, 0xE0, 0xFE, -0xC4, 0x22, 0x90, 0x8E, 0x81, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x8E, 0x8E, 0xE0, 0xFD, 0x7F, 0x93, -0x31, 0x39, 0x90, 0x8E, 0x85, 0xE0, 0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, -0x10, 0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0, 0x7F, 0x08, 0x51, 0x84, 0xEF, 0x44, -0x10, 0xFD, 0x7F, 0x08, 0x31, 0x39, 0x7F, 0x01, 0x12, 0x58, 0xE6, 0x7F, 0x90, 0x51, 0x84, 0xEF, -0x44, 0x01, 0xFD, 0x7F, 0x90, 0x31, 0x39, 0x7F, 0x14, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x7F, 0x58, -0x7E, 0x0C, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, 0xF8, 0xEE, 0xF0, 0xA3, 0xEF, -0xF0, 0x12, 0x37, 0x4E, 0x90, 0x95, 0x02, 0x12, 0x08, 0x6D, 0x90, 0x94, 0xFA, 0x12, 0x43, 0xE5, -0x12, 0x08, 0x3A, 0x90, 0x95, 0x02, 0xF1, 0xF4, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, -0x90, 0x94, 0xFA, 0x12, 0x43, 0xE5, 0x90, 0x94, 0xFE, 0xF1, 0xF4, 0xD0, 0x03, 0xD0, 0x02, 0xD0, -0x01, 0xD0, 0x00, 0x12, 0x43, 0xC7, 0x90, 0x95, 0x06, 0x12, 0x08, 0x6D, 0x90, 0x95, 0x06, 0x12, -0x43, 0xE5, 0x71, 0x91, 0x90, 0x94, 0xF8, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x38, 0x45, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x8C, 0xED, 0xF0, -0xEF, 0x14, 0x60, 0x02, 0xC1, 0xCD, 0x90, 0x06, 0x03, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x95, 0x8C, -0xE0, 0xC4, 0x33, 0x54, 0xE0, 0xFF, 0x90, 0x04, 0x42, 0xE0, 0x54, 0x9F, 0x4F, 0xFF, 0xF0, 0x90, -0x94, 0xFA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0x94, 0xFE, 0x12, 0x08, 0x79, 0x00, -0x00, 0x00, 0x01, 0xF1, 0x34, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0x94, 0xFE, 0x12, -0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x7F, 0x00, 0x7E, 0x09, 0xF1, 0x38, 0x12, 0x08, 0x79, 0x00, -0x00, 0x00, 0x10, 0x90, 0x95, 0x8C, 0x12, 0x65, 0x62, 0xEF, 0x54, 0x03, 0xFF, 0xE4, 0x78, 0x01, -0x12, 0x08, 0x47, 0x78, 0x04, 0x12, 0x83, 0x4D, 0x7F, 0x00, 0x7E, 0x0A, 0xF1, 0x38, 0x12, 0x08, -0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0x95, 0x8C, 0x12, 0x65, 0x62, 0xEF, 0x54, 0x03, 0xFF, 0xE4, -0x78, 0x0A, 0x12, 0x83, 0x4D, 0x7F, 0x00, 0x7E, 0x0D, 0xF1, 0x38, 0x12, 0x08, 0x79, 0x0C, 0x00, -0x00, 0x00, 0x90, 0x95, 0x8C, 0x12, 0x65, 0x62, 0xEF, 0x54, 0x03, 0xFF, 0xE4, 0x78, 0x1A, 0x12, -0x83, 0x4D, 0x7F, 0x18, 0xF1, 0x36, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0x94, 0xFE, -0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x12, 0x9F, 0x8B, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, -0x00, 0x90, 0x94, 0xEC, 0x12, 0x08, 0x79, 0x00, 0x00, 0x04, 0x00, 0x80, 0x59, 0x90, 0x06, 0x03, -0xE0, 0x44, 0x04, 0xF0, 0x90, 0x94, 0xFA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0x94, -0xFE, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x34, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, -0x01, 0x90, 0x94, 0xFE, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x7E, 0x09, 0xF1, -0x38, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0x94, 0xFE, 0x12, 0x08, 0x79, 0x00, 0x00, -0x0C, 0x00, 0x12, 0x9F, 0x8B, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0x94, 0xEC, 0x12, -0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x7D, 0x18, 0x7C, 0x00, 0xE4, 0xFF, 0x12, 0x82, 0x66, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x00, 0x7E, 0x08, 0xB1, 0x92, 0x90, 0x94, 0xFA, 0x22, 0xFD, 0x7F, -0x4E, 0x31, 0x39, 0x7F, 0x4F, 0x51, 0x84, 0xEF, 0x22, 0x7F, 0x67, 0x51, 0x84, 0xEF, 0x44, 0x20, -0xFD, 0x7F, 0x67, 0x31, 0x39, 0x90, 0x95, 0x56, 0xE0, 0x22, 0x90, 0x01, 0x34, 0xF1, 0x9D, 0x90, -0x01, 0x3C, 0xF1, 0x9F, 0xFD, 0x7F, 0x54, 0x31, 0x39, 0x7D, 0xFF, 0x7F, 0x55, 0x31, 0x39, 0x7D, -0xFF, 0x7F, 0x56, 0x31, 0x39, 0x7D, 0xFF, 0x7F, 0x57, 0x21, 0x39, 0x90, 0x01, 0x30, 0xE4, 0xF1, -0x9F, 0x90, 0x01, 0x38, 0xF1, 0x9F, 0xFD, 0x7F, 0x50, 0x31, 0x39, 0xE4, 0xFD, 0x7F, 0x51, 0x31, -0x39, 0xE4, 0xFD, 0x7F, 0x52, 0x31, 0x39, 0xE4, 0xFD, 0x7F, 0x53, 0x21, 0x39, 0x74, 0xFF, 0xF0, -0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0xD3, -0x30, 0xE6, 0x1B, 0x90, 0x00, 0x8C, 0xE0, 0xF5, 0x26, 0x7F, 0x8D, 0x51, 0x84, 0x90, 0x00, 0x8E, -0xE0, 0xF5, 0x27, 0xF1, 0xD3, 0x30, 0xE0, 0x06, 0xE4, 0xFD, 0x7F, 0x8D, 0x31, 0x39, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0x7F, 0x8F, 0x51, 0x84, 0xEF, 0x22, 0x51, 0x84, 0xEF, 0x44, 0x80, 0x22, 0x12, -0x9F, 0xE0, 0x7F, 0xF2, 0x51, 0x84, 0xEF, 0x20, 0xE6, 0x09, 0x7F, 0x05, 0xF1, 0xD9, 0xFD, 0x7F, -0x05, 0x31, 0x39, 0x22, 0x12, 0x43, 0xF1, 0x02, 0x43, 0xBA, 0x22, 0x51, 0x84, 0xEF, 0x44, 0x40, -0xFD, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x3F, 0xEE, 0xF0, 0xA3, 0xEF, -0xF0, 0x90, 0x95, 0x43, 0xE0, 0xF5, 0x3B, 0xA3, 0xE0, 0xF5, 0x3C, 0x12, 0x36, 0x3E, 0x90, 0x95, -0x3F, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0xA3, 0xA3, 0xA3, 0x74, 0x05, 0xF0, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x90, 0x95, 0x4A, 0xF0, 0x7F, 0x03, 0xD3, 0x10, 0xAF, 0x01, 0xC3, -0xC0, 0xD0, 0x90, 0x95, 0x45, 0xEF, 0xF0, 0x12, 0x93, 0x31, 0x90, 0x95, 0x45, 0xE0, 0xFF, 0x31, -0x4A, 0x74, 0x01, 0xF0, 0x90, 0x95, 0x4A, 0xE0, 0xFE, 0xEF, 0x31, 0x58, 0xEE, 0xF0, 0x90, 0x95, -0x45, 0xE0, 0x11, 0x9F, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x11, 0x94, 0x78, 0x10, 0x12, -0x08, 0x47, 0xAB, 0x07, 0x11, 0x94, 0x78, 0x08, 0x12, 0x08, 0x47, 0x90, 0x95, 0x43, 0xEF, 0xF0, -0x11, 0x94, 0x90, 0x95, 0x44, 0xEF, 0xF0, 0x7D, 0x01, 0x7F, 0x50, 0x7E, 0x01, 0x11, 0x02, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0x90, 0x95, 0x46, 0x02, 0x43, 0xE5, 0x90, 0x93, 0xA7, 0xE0, 0xFB, 0x75, -0xF0, 0x0A, 0xA4, 0x24, 0x62, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0xE4, 0x90, 0x93, -0xA7, 0xF0, 0x90, 0x93, 0xA7, 0xE0, 0xFF, 0xC3, 0x94, 0x08, 0x40, 0x02, 0x21, 0x42, 0xEF, 0x31, -0x4A, 0xE0, 0x64, 0x01, 0x70, 0x74, 0x90, 0x93, 0xA7, 0xE0, 0x11, 0x9F, 0x12, 0x43, 0xE5, 0xE4, -0x7B, 0x01, 0x31, 0x43, 0x70, 0x3A, 0x90, 0x93, 0xA7, 0xE0, 0xFB, 0x31, 0x58, 0xE0, 0x60, 0x21, -0x14, 0x70, 0x57, 0xEB, 0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, -0x83, 0x12, 0x43, 0xE5, 0xEB, 0x11, 0x9F, 0x12, 0x08, 0x6D, 0x90, 0x93, 0xA7, 0xE0, 0xFF, 0x80, -0x0B, 0x11, 0x9A, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x03, 0x31, 0x66, 0x80, 0x2A, -0x90, 0x93, 0xA7, 0xE0, 0x11, 0x9F, 0x12, 0x43, 0xE5, 0xE4, 0xFB, 0x31, 0x43, 0x50, 0x1B, 0x11, -0x9A, 0x12, 0x43, 0xE5, 0xEF, 0x24, 0xFF, 0xFF, 0xEE, 0x34, 0xFF, 0xFE, 0xED, 0x34, 0xFF, 0xFD, -0xEC, 0x34, 0xFF, 0xFC, 0xEB, 0x11, 0x9F, 0x12, 0x08, 0x6D, 0x90, 0x93, 0xA7, 0xE0, 0x04, 0xF0, -0x01, 0xB2, 0x22, 0xFA, 0xF9, 0xF8, 0xC3, 0x02, 0x43, 0xD4, 0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x6B, -0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x6A, 0xF5, 0x82, -0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0xEF, 0x24, 0xFC, 0x60, 0x05, 0x04, 0x70, 0x05, 0x80, 0x04, -0x12, 0x81, 0x2C, 0x22, 0xE4, 0x90, 0x93, 0xA8, 0xF0, 0x90, 0x94, 0xD0, 0x04, 0xF0, 0x90, 0x06, -0x32, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x93, 0x73, 0x12, 0x43, 0xE5, 0x12, 0x9F, 0xE7, 0xE4, 0x3D, -0xFD, 0xE4, 0x3C, 0xFC, 0x90, 0x93, 0x73, 0x12, 0x08, 0x6D, 0x12, 0x9C, 0xAC, 0xE4, 0x90, 0x94, -0xB4, 0xF0, 0xFF, 0x12, 0x83, 0x92, 0x12, 0x6B, 0x46, 0x70, 0x27, 0x31, 0xE1, 0x7F, 0x05, 0x7E, -0x00, 0x12, 0x3D, 0xC2, 0x71, 0xD0, 0x90, 0x8E, 0x87, 0xE0, 0x64, 0x02, 0x60, 0x14, 0x90, 0x93, -0xA8, 0xE0, 0x04, 0xF0, 0x12, 0x9F, 0xE0, 0x31, 0xE1, 0x90, 0x93, 0xA8, 0xE0, 0xD3, 0x94, 0x0A, -0x40, 0xE4, 0x90, 0x95, 0x46, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x0A, 0x12, 0x9F, 0xD8, 0x01, -0x3B, 0x7D, 0x01, 0x7F, 0x02, 0x80, 0x04, 0x7D, 0x01, 0x7F, 0x04, 0xD3, 0x10, 0xAF, 0x01, 0xC3, -0xC0, 0xD0, 0x90, 0x95, 0x91, 0xED, 0xF0, 0x90, 0x8E, 0x80, 0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, -0x03, 0x30, 0xE0, 0x02, 0x61, 0x32, 0xEE, 0x12, 0x74, 0x1B, 0x30, 0xE0, 0x02, 0x61, 0x32, 0x90, -0x8E, 0x87, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0x61, 0x32, 0xEF, 0x70, 0x02, 0x41, 0xAA, 0x24, 0xFE, -0x70, 0x02, 0x41, 0xE4, 0x24, 0xFE, 0x60, 0x4A, 0x24, 0xFC, 0x70, 0x02, 0x61, 0x1F, 0x24, 0xFC, -0x60, 0x02, 0x61, 0x32, 0xEE, 0xB4, 0x0E, 0x02, 0x71, 0x55, 0x90, 0x8E, 0x87, 0xE0, 0x70, 0x04, -0x7F, 0x01, 0x71, 0x91, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x06, 0x02, 0x71, 0x70, 0x90, 0x8E, 0x87, -0xE0, 0xB4, 0x04, 0x0F, 0x90, 0x95, 0x91, 0xE0, 0xFF, 0x60, 0x05, 0x12, 0x9B, 0x11, 0x80, 0x03, -0x12, 0x6D, 0x8A, 0x90, 0x8E, 0x87, 0xE0, 0x64, 0x08, 0x60, 0x02, 0x61, 0x32, 0x12, 0x9B, 0x87, -0x61, 0x32, 0x90, 0x8E, 0x87, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x71, 0x91, 0x90, 0x8E, 0x87, 0xE0, -0xB4, 0x06, 0x02, 0x71, 0x70, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0x37, 0xBF, 0x01, -0x02, 0x71, 0x55, 0x90, 0x8E, 0x87, 0xE0, 0x64, 0x0C, 0x60, 0x02, 0x61, 0x32, 0x71, 0x37, 0xEF, -0x64, 0x01, 0x60, 0x02, 0x61, 0x32, 0x71, 0xA7, 0x61, 0x32, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x0E, -0x07, 0x71, 0x37, 0xBF, 0x01, 0x02, 0x71, 0x55, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x06, 0x02, 0x71, -0x70, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x0C, 0x07, 0x71, 0x37, 0xBF, 0x01, 0x02, 0x71, 0xA7, 0x90, -0x8E, 0x87, 0xE0, 0x64, 0x04, 0x70, 0x5B, 0x12, 0x9A, 0x5A, 0xEF, 0x64, 0x01, 0x70, 0x53, 0x12, -0x9B, 0x43, 0x80, 0x4E, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0x37, 0xBF, 0x01, 0x02, -0x71, 0x55, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x06, 0x02, 0x71, 0x70, 0x90, 0x8E, 0x87, 0xE0, 0xB4, -0x0C, 0x07, 0x71, 0x37, 0xBF, 0x01, 0x02, 0x71, 0xA7, 0x90, 0x8E, 0x87, 0xE0, 0x70, 0x04, 0x7F, -0x01, 0x71, 0x91, 0x90, 0x8E, 0x87, 0xE0, 0xB4, 0x04, 0x18, 0x12, 0x9B, 0x5E, 0x80, 0x13, 0x90, -0x8E, 0x87, 0xE0, 0xB4, 0x0C, 0x0C, 0x90, 0x8E, 0x81, 0x12, 0x84, 0x0B, 0x30, 0xE0, 0x03, 0x12, -0x9B, 0x76, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x9A, 0x41, 0xBF, 0x01, 0x15, 0x90, 0x8E, 0x80, -0x12, 0x9E, 0xBD, 0x20, 0xE0, 0x0C, 0x90, 0x8E, 0x86, 0xE0, 0xD3, 0x94, 0x04, 0x50, 0x03, 0x7F, -0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x8E, 0x81, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04, 0x7D, 0x0C, -0x80, 0x05, 0x12, 0x8D, 0x28, 0x7D, 0x04, 0x7F, 0x01, 0x71, 0xDC, 0xE4, 0xFD, 0xFF, 0x81, 0x51, -0x90, 0x8E, 0x81, 0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, 0x08, 0xE0, 0x44, 0x40, 0xF0, 0x7D, 0x04, -0x80, 0x06, 0xE0, 0x54, 0x7F, 0xF0, 0x7D, 0x0C, 0x7F, 0x01, 0x71, 0xDC, 0xE4, 0xFD, 0xFF, 0x81, -0x51, 0x90, 0x95, 0x90, 0xEF, 0xF0, 0x12, 0x6F, 0x13, 0x90, 0x95, 0x90, 0xE0, 0x60, 0x02, 0xF1, -0xF3, 0x7D, 0x04, 0x7F, 0x01, 0x80, 0x35, 0x12, 0x6B, 0x46, 0x70, 0x23, 0x90, 0x8E, 0x81, 0xE0, -0x54, 0xFD, 0xF0, 0x7D, 0x2C, 0x7F, 0x6F, 0x91, 0x51, 0x7D, 0x08, 0x7F, 0x01, 0xF1, 0x87, 0xBF, -0x01, 0x0D, 0x90, 0x8E, 0x80, 0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E, 0x7F, 0x01, 0x71, 0xDC, 0x22, -0x90, 0x8E, 0x86, 0xE0, 0x90, 0x94, 0xCC, 0xF0, 0x7D, 0x02, 0x7F, 0x02, 0xD3, 0x10, 0xAF, 0x01, -0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x8F, 0xEF, 0xF0, 0x14, 0x60, 0x15, 0x14, 0x60, 0x19, 0x24, 0x02, -0x70, 0x1A, 0xED, 0x54, 0x01, 0xFF, 0x90, 0x8E, 0x80, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x80, 0x0C, -0x90, 0x8E, 0x87, 0xED, 0xF0, 0x80, 0x05, 0x90, 0x8E, 0x86, 0xED, 0xF0, 0x12, 0x4F, 0xD3, 0x30, -0xE4, 0x31, 0x90, 0x95, 0x8F, 0xE0, 0x14, 0x60, 0x07, 0x14, 0x60, 0x1D, 0x24, 0x02, 0x70, 0x23, -0x90, 0x8E, 0x80, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, 0xFF, 0x90, 0x8E, 0x87, -0xE0, 0x54, 0x7F, 0x4F, 0xFD, 0x7F, 0x88, 0x80, 0x07, 0x90, 0x8E, 0x86, 0xE0, 0xFD, 0x7F, 0x89, -0x12, 0x49, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xFD, 0x7F, 0x0C, 0x31, 0xEB, 0xE4, 0xFD, -0xFF, 0x90, 0x05, 0x22, 0xEF, 0xF0, 0x90, 0x8D, 0x05, 0xED, 0xF0, 0x22, 0x90, 0x93, 0xD4, 0x12, -0x44, 0x12, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x93, 0xE5, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x09, -0x7D, 0x39, 0xF1, 0xF8, 0xBF, 0x01, 0x10, 0x80, 0x00, 0x90, 0x93, 0x7B, 0x12, 0x7A, 0x5E, 0x90, -0x93, 0xE2, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0xE2, 0x12, 0x8B, 0x87, 0x90, 0x93, 0xE4, -0xEF, 0xF0, 0x90, 0x93, 0xE2, 0x12, 0x8D, 0x1C, 0x90, 0x93, 0xE0, 0xE0, 0xFD, 0x12, 0x8B, 0xCD, -0x90, 0x93, 0xE1, 0xE0, 0x60, 0x02, 0xA1, 0x29, 0xD1, 0xF6, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, -0x90, 0x93, 0xD7, 0xD1, 0xE5, 0x75, 0x43, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xB1, 0xC8, -0xF1, 0xDD, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x93, 0xD4, 0xD1, 0xE5, 0x75, 0x43, 0x10, -0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xB1, 0xC8, 0xD1, 0xF9, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, -0xD1, 0xE2, 0x75, 0x43, 0x10, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xB1, 0xC8, 0x24, 0x60, 0xF9, -0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0xD1, 0xE2, 0x75, 0x43, -0x10, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xB1, 0xC8, 0x24, 0x72, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, -0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x93, 0xDD, 0xD1, 0xE5, 0x75, 0x43, 0x06, -0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, 0x93, 0xDA, 0x12, 0x44, 0x09, 0x90, -0x94, 0x12, 0x12, 0x44, 0x12, 0x90, 0x94, 0x15, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x20, 0x90, -0x94, 0x19, 0x74, 0x3A, 0xF0, 0x90, 0x93, 0xD4, 0x12, 0x44, 0x09, 0x12, 0x98, 0x24, 0xB1, 0xCB, -0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC, 0x75, 0x40, 0x01, 0xF5, 0x41, 0x89, 0x42, 0x75, 0x43, 0x28, -0x7B, 0x01, 0x7A, 0x93, 0x79, 0xE7, 0xB1, 0xC8, 0x12, 0x9F, 0x96, 0xC0, 0x03, 0x8B, 0x40, 0x75, -0x41, 0x8F, 0x75, 0x42, 0xD1, 0x75, 0x43, 0x28, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, 0x93, 0xE4, -0xE0, 0xFF, 0x90, 0x93, 0xE3, 0xE0, 0x2F, 0xFF, 0x90, 0x93, 0xE2, 0xE0, 0x34, 0x00, 0xCF, 0x24, -0x30, 0xFD, 0xE4, 0x3F, 0xFC, 0x90, 0x93, 0x7B, 0xE0, 0xFB, 0x7F, 0x3A, 0x12, 0x61, 0x65, 0xB1, -0xCB, 0x12, 0x9F, 0x96, 0xC0, 0x03, 0x8B, 0x40, 0x75, 0x41, 0x93, 0x75, 0x42, 0xE7, 0x75, 0x43, -0x28, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, 0x06, 0x33, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x93, 0xE5, -0xE0, 0xFF, 0x7D, 0x3A, 0x91, 0x51, 0xE1, 0xEC, 0x12, 0x35, 0x26, 0x90, 0x93, 0xE2, 0xA3, 0xE0, -0xFF, 0xA3, 0xE0, 0x2F, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x0A, 0x12, -0x44, 0x12, 0x78, 0x16, 0x7C, 0x95, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x64, 0x12, 0x97, -0xBD, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x95, 0x15, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x09, 0x7D, -0x33, 0xF1, 0xF8, 0xBF, 0x01, 0x10, 0x80, 0x00, 0x90, 0x93, 0x7A, 0x12, 0x7A, 0x5E, 0x90, 0x95, -0x12, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x95, 0x12, 0x12, 0x8B, 0x87, 0x90, 0x95, 0x14, 0xEF, -0xF0, 0x90, 0x95, 0x12, 0x12, 0x8D, 0x1C, 0x90, 0x95, 0x10, 0xE0, 0xFD, 0x12, 0x8B, 0xCD, 0x90, -0x95, 0x11, 0xE0, 0x70, 0x4D, 0xD1, 0xF6, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x95, 0x0D, -0xD1, 0xE5, 0x75, 0x43, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xD1, 0xEF, 0xB1, 0xCE, 0xF1, -0x61, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x95, 0x0D, 0xD1, 0xE5, 0x75, -0x43, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xD1, 0xEF, 0xB1, 0xCE, 0xF1, 0xDD, 0xC0, 0x03, -0xC0, 0x02, 0xC0, 0x01, 0x90, 0x95, 0x0A, 0xD1, 0xE5, 0x75, 0x43, 0x04, 0xD0, 0x01, 0xD0, 0x02, -0x80, 0x44, 0x90, 0x95, 0x11, 0xE0, 0x64, 0x01, 0x70, 0x41, 0xD1, 0xF6, 0xC0, 0x03, 0x8B, 0x40, -0x75, 0x41, 0x8F, 0x75, 0x42, 0x4D, 0x75, 0x43, 0x06, 0xD0, 0x03, 0xD1, 0xEF, 0xB1, 0xCE, 0xF1, -0x61, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0x8B, 0x40, 0x75, 0x41, 0x8F, 0x75, 0x42, 0x57, 0x75, 0x43, -0x06, 0xD0, 0x03, 0xD1, 0xEF, 0xB1, 0xCE, 0xF1, 0xDD, 0xC0, 0x03, 0x8B, 0x40, 0x75, 0x41, 0x8F, -0x75, 0x42, 0x5D, 0x75, 0x43, 0x04, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, 0x06, 0x30, 0xE0, 0x44, -0x10, 0xF0, 0x90, 0x95, 0x15, 0xE0, 0xFF, 0x7D, 0x34, 0x91, 0x51, 0xF1, 0xEC, 0xD0, 0xD0, 0x92, -0xAF, 0x22, 0x90, 0x93, 0xDA, 0x12, 0x44, 0x09, 0x8B, 0x40, 0x8A, 0x41, 0x89, 0x42, 0x22, 0x12, -0x35, 0x26, 0x90, 0x95, 0x12, 0x22, 0xA3, 0xA3, 0xE0, 0x24, 0x38, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, -0x7B, 0x01, 0x22, 0x12, 0x66, 0x44, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0xAB, 0x12, 0x8B, -0x87, 0x90, 0x93, 0xAD, 0xEF, 0xF0, 0x90, 0x93, 0xAB, 0xA3, 0xE0, 0x24, 0x38, 0xF9, 0xE4, 0x34, -0xFC, 0x12, 0x9F, 0x1D, 0x7A, 0x8F, 0x79, 0x4D, 0xF1, 0x5A, 0xB1, 0xCE, 0x24, 0x3E, 0xF9, 0xE4, -0x34, 0xFC, 0x12, 0x83, 0xD0, 0x7A, 0x8F, 0x79, 0x53, 0xF1, 0x5A, 0xB1, 0xCE, 0xF1, 0x61, 0x12, -0x9F, 0x1D, 0x7A, 0x8F, 0x79, 0x57, 0xF1, 0x5A, 0xB1, 0xCE, 0x24, 0x48, 0xF9, 0xE4, 0x34, 0xFC, -0x12, 0x83, 0xD0, 0x7A, 0x8F, 0x79, 0x5D, 0x02, 0x35, 0x26, 0x12, 0x35, 0x26, 0x90, 0x93, 0xAB, -0x22, 0x24, 0x42, 0xF9, 0xE4, 0x34, 0xFC, 0x22, 0x90, 0x8E, 0x84, 0xE0, 0x64, 0x01, 0x70, 0x12, -0x12, 0x7F, 0x0A, 0x60, 0x05, 0x91, 0x48, 0x02, 0x79, 0xEE, 0x90, 0x8E, 0x87, 0xE0, 0x70, 0x02, -0x31, 0xE7, 0x22, 0x7D, 0x08, 0xE4, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, -0x51, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x8D, 0x03, 0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D, 0xE0, -0x60, 0x27, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x95, 0x55, 0xF0, 0x7D, 0x26, 0xF1, 0xF8, 0xEF, 0x64, -0x01, 0x70, 0x03, 0x12, 0x7E, 0x35, 0x90, 0x95, 0x55, 0xE0, 0xFF, 0x7D, 0x27, 0x91, 0x51, 0x90, -0x95, 0x51, 0xE0, 0xFF, 0x12, 0x8A, 0x97, 0x80, 0x0B, 0x90, 0x95, 0x51, 0xE0, 0xFF, 0x12, 0x8A, -0x97, 0x12, 0x7E, 0x35, 0xF1, 0xEC, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x24, 0x48, 0xF9, -0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x04, 0x1F, 0x74, -0x20, 0xF0, 0x22, 0xE4, 0xFD, 0xFF, 0x81, 0x51, 0x7F, 0xFF, 0x91, 0x51, 0xE4, 0x90, 0x95, 0x81, -0xF0, 0xA3, 0xF0, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x0F, 0xA3, 0xE0, 0x70, 0x0B, 0xA3, 0xE0, 0x70, -0x07, 0xA3, 0xE0, 0x70, 0x03, 0x7F, 0x01, 0x22, 0xD3, 0x90, 0x95, 0x82, 0xE0, 0x94, 0xE8, 0x90, -0x95, 0x81, 0xE0, 0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x20, 0xF0, 0x7F, 0x00, -0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0x90, 0x95, 0x81, 0xE4, 0x75, 0xF0, 0x01, 0x12, -0x08, 0xD6, 0x80, 0xBF, 0x02, 0x4F, 0xA7, 0xE4, 0x90, 0x93, 0x9D, 0xF0, 0x90, 0x93, 0x9D, 0xE0, -0x64, 0x01, 0xF0, 0x24, 0x47, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x58, 0xA3, 0xF0, 0x12, 0x3E, 0x44, -0xBF, 0x01, 0x03, 0x12, 0x31, 0xFC, 0xC2, 0xAF, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x0F, 0x90, 0x8E, -0x87, 0xE0, 0xFF, 0x90, 0x8E, 0x86, 0xE0, 0x6F, 0x60, 0x03, 0x12, 0x79, 0x32, 0xC2, 0xAF, 0x12, -0x91, 0xC9, 0xBF, 0x01, 0x02, 0x11, 0x9B, 0xD2, 0xAF, 0xD2, 0xAF, 0x90, 0x93, 0x95, 0xE0, 0xB4, -0x01, 0x02, 0x31, 0x3D, 0x11, 0x44, 0x12, 0x46, 0x38, 0x80, 0xB1, 0x90, 0x8E, 0x80, 0xE0, 0x30, -0xE0, 0x02, 0x11, 0xA5, 0x22, 0x90, 0x8E, 0x87, 0xE0, 0xFF, 0x60, 0x03, 0xB4, 0x08, 0x08, 0x12, -0x9A, 0xDB, 0xBF, 0x01, 0x02, 0x11, 0xB8, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, -0x4D, 0x42, 0x11, 0xC9, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x92, 0xF9, 0x7F, 0x08, 0x12, 0x4A, -0x84, 0xEF, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x49, 0x39, 0xE4, 0xFF, 0x11, 0xE6, 0x90, 0x8E, -0x81, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x95, 0x78, 0xEF, 0x31, 0xBE, 0x90, 0x01, 0x09, 0xE0, -0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x90, 0x95, 0x78, 0xE0, 0x6F, 0x60, 0x3E, 0xC3, 0x90, -0x95, 0x7A, 0xE0, 0x94, 0x88, 0x90, 0x95, 0x79, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, -0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90, 0x95, 0x79, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x08, 0xD6, 0x7F, -0x14, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0xD3, 0x90, 0x95, 0x7A, 0xE0, 0x94, 0x32, 0x90, 0x95, 0x79, -0xE0, 0x94, 0x00, 0x40, 0xB7, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0, 0xB0, 0x22, 0xD3, 0x10, 0xAF, -0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x37, 0x4E, 0x90, 0x93, 0x9E, 0x12, 0x08, -0x6D, 0x7F, 0x00, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0x90, 0x93, 0xA2, 0x12, 0x08, 0x6D, 0x90, 0x93, -0x9E, 0x31, 0xB1, 0x60, 0x1C, 0x90, 0x93, 0x9E, 0x31, 0xA9, 0xEC, 0x90, 0x93, 0x9E, 0x12, 0x08, -0x6D, 0x90, 0x93, 0x9E, 0x12, 0x43, 0xE5, 0x12, 0x4B, 0x91, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x38, -0x45, 0x90, 0x93, 0xA2, 0x31, 0xB1, 0x60, 0x1C, 0x90, 0x93, 0xA2, 0x31, 0xA9, 0xEC, 0x90, 0x93, -0xA2, 0x12, 0x08, 0x6D, 0x90, 0x93, 0xA2, 0x12, 0x43, 0xE5, 0x12, 0x4B, 0x91, 0x7F, 0x00, 0x7E, -0x09, 0x12, 0x38, 0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x43, 0xE5, 0xEF, 0x54, 0xFE, 0xFF, -0x22, 0x12, 0x43, 0xE5, 0xEF, 0x54, 0x01, 0xFF, 0xE4, 0xFE, 0xFD, 0xFC, 0xEF, 0x22, 0xF0, 0xE4, -0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x94, 0xDA, -0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0x31, 0xBE, 0x90, 0x94, 0xE2, 0xF0, 0xA3, 0xF0, -0xA3, 0xF0, 0x90, 0x01, 0xC4, 0x74, 0xC5, 0xF0, 0x74, 0x59, 0xA3, 0xF0, 0x90, 0x01, 0x1F, 0xE0, -0xFE, 0x90, 0x01, 0x1E, 0x12, 0x61, 0x5C, 0x90, 0x94, 0xD1, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x02, -0x82, 0xE0, 0x90, 0x94, 0xD9, 0xF0, 0x90, 0x8F, 0x2E, 0xE0, 0x20, 0xE0, 0x02, 0x81, 0xC3, 0xE4, -0x90, 0x94, 0xD8, 0xF0, 0x90, 0x94, 0xD9, 0xE0, 0xFF, 0x90, 0x94, 0xD8, 0xE0, 0xC3, 0x9F, 0x40, -0x02, 0x81, 0xC3, 0x90, 0x94, 0xD1, 0x12, 0xA0, 0x2F, 0x90, 0xFD, 0x11, 0xF0, 0x90, 0x94, 0xE2, -0xEF, 0xF0, 0x12, 0x8E, 0xFA, 0x12, 0x9E, 0xFC, 0x54, 0x3F, 0xFE, 0x90, 0x94, 0xD3, 0xF0, 0xA3, -0xEF, 0xF0, 0x90, 0x94, 0xDE, 0xEE, 0x12, 0x8F, 0xAC, 0xE0, 0x54, 0x03, 0xFE, 0xEF, 0x24, 0x18, -0x2E, 0xFF, 0x90, 0x94, 0xE3, 0xF0, 0x90, 0x94, 0xD2, 0xE0, 0x2F, 0xFF, 0x90, 0x94, 0xD1, 0xE0, -0x34, 0x00, 0xFE, 0x90, 0x94, 0xD5, 0xF1, 0xE0, 0xC0, 0x07, 0x91, 0xD3, 0x7D, 0x01, 0x91, 0xFE, -0xC0, 0x07, 0x91, 0xD3, 0x7D, 0x04, 0x91, 0xFE, 0xAB, 0x07, 0xD0, 0x05, 0xD0, 0x07, 0x12, 0x8B, -0xAD, 0x90, 0x94, 0xDA, 0xEF, 0xF0, 0x91, 0xD3, 0xE4, 0xFD, 0x91, 0xFE, 0xEF, 0x54, 0xFC, 0x90, -0x94, 0xD7, 0xF0, 0x90, 0x94, 0xE3, 0xE0, 0xFF, 0x90, 0x94, 0xD3, 0xE4, 0x8F, 0xF0, 0x12, 0x08, -0xD6, 0x90, 0x94, 0xD3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x93, 0x78, 0x90, 0x94, 0xD3, 0xEE, -0xF0, 0xA3, 0xEF, 0xF0, 0xF1, 0xF1, 0xFF, 0x7D, 0x0F, 0x91, 0xFE, 0x90, 0x94, 0xD3, 0xE0, 0xFC, -0xA3, 0xE0, 0xFD, 0x90, 0x94, 0xD1, 0xEC, 0x8D, 0xF0, 0x12, 0x8F, 0xDE, 0xFC, 0xA3, 0xE0, 0xFD, -0xD3, 0x90, 0x94, 0xD2, 0xE0, 0x9D, 0x90, 0x94, 0xD1, 0xE0, 0x9C, 0x40, 0x18, 0x90, 0x8D, 0xF9, -0xE0, 0x24, 0x01, 0xFD, 0x12, 0x9F, 0x09, 0xFC, 0xC3, 0x90, 0x94, 0xD2, 0xE0, 0x9D, 0xF0, 0x90, -0x94, 0xD1, 0xE0, 0x9C, 0xF0, 0xEF, 0x30, 0xE6, 0x06, 0x90, 0x01, 0xC7, 0x74, 0x22, 0xF0, 0xEF, -0x30, 0xE7, 0x06, 0x90, 0x01, 0xC7, 0x74, 0x21, 0xF0, 0xEF, 0x30, 0xE5, 0x06, 0x90, 0x01, 0xC7, -0x74, 0x23, 0xF0, 0x90, 0x94, 0xD0, 0xE0, 0x60, 0x41, 0x90, 0x94, 0xD7, 0xE0, 0x24, 0xB0, 0x60, -0x19, 0x24, 0xD0, 0x60, 0x02, 0x81, 0x5F, 0x12, 0xA0, 0x27, 0x20, 0xE0, 0x1E, 0xEF, 0x13, 0x13, -0x13, 0x54, 0x1F, 0x20, 0xE0, 0x02, 0x81, 0x5F, 0x80, 0x11, 0x12, 0xA0, 0x27, 0x20, 0xE0, 0x0B, -0xEF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x20, 0xE0, 0x02, 0x81, 0x5F, 0x91, 0xD3, 0x90, 0x94, 0xDE, -0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x73, 0xB6, 0x81, 0x5F, 0x90, 0x94, 0xD7, 0xE0, 0x24, 0x40, -0x60, 0x04, 0x24, 0x20, 0x70, 0x2B, 0x90, 0x8F, 0x31, 0x12, 0x74, 0x19, 0x20, 0xE0, 0x02, 0x81, -0x5F, 0x90, 0x8F, 0x43, 0xE0, 0x04, 0xF0, 0x91, 0xD3, 0x12, 0x94, 0x35, 0xEF, 0x70, 0x02, 0x81, -0x5F, 0x90, 0x94, 0xD7, 0xE0, 0xFF, 0x12, 0x94, 0x23, 0x90, 0x8F, 0x44, 0xE0, 0x04, 0xF0, 0x81, -0x5F, 0xF1, 0xF9, 0x30, 0xE0, 0x5C, 0x90, 0x94, 0xDA, 0xE0, 0xFF, 0x90, 0x94, 0xD6, 0xE0, 0x2F, -0xFF, 0x90, 0x94, 0xD5, 0xE0, 0x34, 0x00, 0xCF, 0x24, 0x08, 0xCF, 0x34, 0x00, 0xFE, 0x90, 0x94, -0xE0, 0xF1, 0xE0, 0xEF, 0x64, 0x45, 0x70, 0x3A, 0xB1, 0xB3, 0x12, 0x9E, 0x33, 0xEF, 0x64, 0x01, -0x70, 0x30, 0xB1, 0xB3, 0x12, 0x9E, 0x77, 0xEF, 0x64, 0x01, 0x70, 0x26, 0x90, 0x94, 0xE4, 0x04, -0xF0, 0xB1, 0xB3, 0xA3, 0xE0, 0xFD, 0x12, 0x9D, 0x97, 0xEF, 0x70, 0x0E, 0x90, 0x94, 0xE2, 0xE0, -0xFD, 0x90, 0xFD, 0x11, 0xF0, 0xB1, 0xB3, 0x12, 0x9D, 0xF0, 0x90, 0x94, 0xE2, 0xE0, 0x90, 0xFD, -0x11, 0xF0, 0x91, 0xD3, 0x12, 0x94, 0x35, 0xEF, 0x60, 0x1F, 0x91, 0xD3, 0x90, 0x94, 0xDA, 0xE0, -0xFD, 0x90, 0x94, 0xDD, 0xE0, 0xFB, 0x90, 0x94, 0xE2, 0xE0, 0x90, 0x93, 0xAB, 0xF0, 0xB1, 0x2D, -0xEF, 0x60, 0x06, 0x90, 0x94, 0xE4, 0x74, 0x01, 0xF0, 0x90, 0x8F, 0x2E, 0xE0, 0xC3, 0x13, 0x30, -0xE0, 0x13, 0x91, 0xD3, 0x90, 0x94, 0xDA, 0xE0, 0xFD, 0x12, 0x94, 0x8D, 0xEF, 0x60, 0x06, 0x90, -0x94, 0xE4, 0x74, 0x01, 0xF0, 0x12, 0x87, 0xDE, 0x54, 0x3F, 0x30, 0xE0, 0x0A, 0x91, 0xD3, 0x90, -0x94, 0xDA, 0xE0, 0xFD, 0x12, 0x95, 0xEC, 0x90, 0x8F, 0x2E, 0x12, 0x74, 0x19, 0x30, 0xE0, 0x0F, -0x90, 0x94, 0xE4, 0xE0, 0x70, 0x09, 0x91, 0xD3, 0x90, 0x94, 0xDA, 0xE0, 0xFD, 0xF1, 0x29, 0x12, -0x98, 0x63, 0xEF, 0x64, 0x01, 0x60, 0x07, 0x90, 0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x05, 0x7F, 0x01, -0x12, 0x73, 0xCF, 0x12, 0x93, 0xFD, 0xEF, 0x64, 0x01, 0x70, 0x37, 0x90, 0x8F, 0x45, 0xE0, 0x04, -0xF0, 0x12, 0x93, 0x9A, 0xAD, 0x07, 0xEF, 0x64, 0x01, 0x60, 0x1F, 0xF1, 0xD8, 0xED, 0xB4, 0x02, -0x08, 0x90, 0x01, 0xC7, 0x74, 0x42, 0xF0, 0x80, 0x0A, 0xED, 0xB4, 0x04, 0x06, 0x90, 0x01, 0xC7, -0x74, 0x43, 0xF0, 0x7F, 0x01, 0x12, 0x73, 0xCF, 0x80, 0x19, 0xF1, 0xF1, 0xFF, 0x12, 0x93, 0x6A, -0x80, 0x09, 0x90, 0x8F, 0x2E, 0xE0, 0x54, 0xFE, 0xF0, 0x80, 0x08, 0x90, 0x94, 0xD8, 0xE0, 0x04, -0xF0, 0x41, 0x14, 0x74, 0xC5, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x59, 0xA3, 0xF0, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0x90, 0x94, 0xD5, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x93, 0xA9, 0xE0, -0xFD, 0x90, 0x93, 0xA8, 0xE0, 0x2D, 0xFD, 0x90, 0x93, 0xA7, 0xE0, 0x34, 0x00, 0xCD, 0x24, 0x10, -0xCD, 0x34, 0x00, 0xFC, 0x7E, 0x00, 0xED, 0x2F, 0xFF, 0xEE, 0x3C, 0xFE, 0xE4, 0xFD, 0xAB, 0x07, -0xAA, 0x06, 0xED, 0x2B, 0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0x90, 0x8D, 0xF9, 0xE0, 0x9B, 0x90, 0x8D, -0xF8, 0xE0, 0x9A, 0x50, 0x0C, 0xA3, 0x12, 0x9F, 0x05, 0xFE, 0xC3, 0xEB, 0x9F, 0xFB, 0xEA, 0x9E, -0xFA, 0x12, 0x8F, 0xD6, 0x74, 0x00, 0x2F, 0x12, 0x8F, 0x09, 0xE0, 0xFF, 0x22, 0x90, 0x93, 0xA9, -0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x12, 0x9E, 0x6E, 0xE4, 0x90, 0x93, 0xAC, 0xF0, 0xFD, 0x91, 0xFE, -0xEF, 0x54, 0x0C, 0x64, 0x08, 0x70, 0x5C, 0xB1, 0xAA, 0xA3, 0xE0, 0xF1, 0xD0, 0x64, 0x88, 0x70, -0x52, 0xB1, 0xAA, 0xA3, 0xE0, 0x24, 0x07, 0xFD, 0x91, 0xFE, 0xEF, 0x64, 0x8E, 0x70, 0x44, 0x90, -0x93, 0xAC, 0x04, 0xB1, 0xA9, 0x12, 0x9F, 0x3F, 0x04, 0xFD, 0x91, 0xFE, 0xEF, 0x64, 0x03, 0x70, -0x32, 0xB1, 0xAA, 0x12, 0x9F, 0x3F, 0xF1, 0xD0, 0x30, 0xE3, 0x07, 0x90, 0x01, 0xC7, 0x74, 0x01, -0x80, 0x1F, 0x90, 0x8F, 0x2E, 0x12, 0x9E, 0xBD, 0x30, 0xE0, 0x09, 0xB1, 0xAA, 0xA3, 0xE0, 0xFD, -0xB1, 0xF0, 0x80, 0x0F, 0x90, 0x8F, 0x31, 0xF1, 0xFC, 0x30, 0xE0, 0x07, 0x90, 0x01, 0xC7, 0x74, -0x02, 0xF1, 0xD7, 0x90, 0x93, 0xAC, 0xE0, 0xFF, 0x22, 0xF0, 0x90, 0x93, 0xA7, 0xE0, 0xFE, 0xA3, -0xE0, 0xFF, 0x22, 0x90, 0x94, 0xE0, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x12, 0xA0, 0x3F, 0xF0, -0x7D, 0x09, 0x91, 0xFE, 0xEF, 0x64, 0x06, 0x70, 0x24, 0xF1, 0xE8, 0x7D, 0x14, 0x91, 0xFE, 0xEF, -0x70, 0x1B, 0xF1, 0xE8, 0x7D, 0x15, 0x91, 0xFE, 0xEF, 0x64, 0x50, 0x70, 0x10, 0xF1, 0xE8, 0x7D, -0x21, 0x91, 0xFE, 0xEF, 0x20, 0xE0, 0x03, 0x30, 0xE2, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x06, 0x31, 0xE0, 0x54, 0xEF, 0x44, 0x08, 0xF0, -0xED, 0x2F, 0xFF, 0xE4, 0x3E, 0xFE, 0x7C, 0x00, 0xEF, 0x24, 0x08, 0xFF, 0xEC, 0x3E, 0x90, 0x93, -0xB0, 0xF0, 0xA3, 0xEF, 0xF0, 0x7E, 0x00, 0x7F, 0x83, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x90, 0x79, -0x43, 0x12, 0x08, 0xAA, 0x90, 0x93, 0xB1, 0xE0, 0x24, 0x01, 0xF1, 0x16, 0x90, 0x90, 0x44, 0xF1, -0x22, 0x24, 0x04, 0xF1, 0x16, 0x90, 0x90, 0x47, 0xF1, 0x22, 0x24, 0x05, 0xF1, 0x16, 0x90, 0x90, -0x48, 0xF1, 0x22, 0x24, 0x06, 0xF1, 0x16, 0x90, 0x90, 0x49, 0xF1, 0x22, 0x24, 0x07, 0xF1, 0x16, -0x90, 0x90, 0x4A, 0xF1, 0x22, 0x24, 0x08, 0xF1, 0x16, 0x90, 0x90, 0x4B, 0xEF, 0xF0, 0xE4, 0x90, -0x93, 0xAF, 0xF0, 0x90, 0x93, 0xAF, 0xE0, 0xFF, 0xC3, 0x94, 0x08, 0x50, 0x1D, 0x90, 0x93, 0xB1, -0xE0, 0x24, 0x09, 0xFD, 0x90, 0x93, 0xB0, 0xE0, 0x91, 0xF1, 0x90, 0x93, 0xAF, 0xE0, 0x24, 0x4C, -0xF5, 0x82, 0xE4, 0x34, 0x90, 0x12, 0x9F, 0x6A, 0x80, 0xD9, 0xE4, 0x90, 0x93, 0xAF, 0xF0, 0x90, -0x93, 0xAF, 0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x50, 0x1D, 0x90, 0x93, 0xB1, 0xE0, 0x24, 0x63, 0xFD, -0x90, 0x93, 0xB0, 0xE0, 0x91, 0xF1, 0x90, 0x93, 0xAF, 0xE0, 0x24, 0xA6, 0xF5, 0x82, 0xE4, 0x34, -0x90, 0x12, 0x9F, 0x6A, 0x80, 0xD9, 0x90, 0x90, 0x48, 0x12, 0x9C, 0xA4, 0x12, 0x8F, 0xCE, 0xF0, -0x30, 0xE3, 0x0D, 0x7F, 0x01, 0x12, 0x73, 0xCF, 0x90, 0x01, 0xC7, 0x74, 0x03, 0xF0, 0x80, 0x3F, -0x90, 0x93, 0xAD, 0xA3, 0xE0, 0xFF, 0x7C, 0x00, 0x54, 0x07, 0xFD, 0x64, 0x01, 0x60, 0x05, 0xED, -0x64, 0x02, 0x70, 0x2B, 0xED, 0x64, 0x02, 0x4C, 0x70, 0x25, 0xEF, 0x54, 0x30, 0xFF, 0xE4, 0xC4, -0xF8, 0x54, 0xF0, 0xC8, 0xEF, 0xC4, 0x54, 0x0F, 0x48, 0x90, 0x90, 0xDC, 0xF0, 0xAE, 0x04, 0xAF, -0x05, 0xE4, 0xFD, 0x12, 0x9B, 0x94, 0x90, 0x06, 0x31, 0xE0, 0x54, 0xF7, 0x44, 0x10, 0xF0, 0x7F, -0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xFF, 0x90, 0x93, 0xB0, 0xE0, 0x34, 0x00, 0xFE, 0xE4, 0xFD, -0x81, 0xFE, 0xEF, 0xF0, 0x90, 0x93, 0xB1, 0xE0, 0x22, 0x12, 0x97, 0xE1, 0x12, 0x97, 0xCB, 0x7B, -0xFF, 0x7A, 0x40, 0x79, 0x90, 0x12, 0x97, 0xBD, 0x78, 0xB1, 0x7C, 0x93, 0x7D, 0x01, 0x7B, 0xFF, -0x7A, 0x40, 0x79, 0x96, 0x12, 0x97, 0xC4, 0xB1, 0xAA, 0x12, 0x94, 0x35, 0xEF, 0x70, 0x02, 0xE1, -0xCF, 0x12, 0x95, 0xDA, 0xFE, 0x90, 0x93, 0xB5, 0xF0, 0xA3, 0xEF, 0xF0, 0x24, 0x06, 0xFF, 0xE4, -0x3E, 0xF1, 0x1D, 0xEF, 0x64, 0x08, 0x70, 0x67, 0x90, 0x93, 0xB6, 0xE0, 0x24, 0x07, 0xFF, 0x90, -0x93, 0xB5, 0xF1, 0x1A, 0xEF, 0x70, 0x58, 0x90, 0x93, 0xB0, 0xF0, 0x90, 0x93, 0xB0, 0xE0, 0xFF, -0xC3, 0x94, 0x04, 0x50, 0x24, 0x90, 0x93, 0xB6, 0xE0, 0x24, 0x18, 0xFD, 0x90, 0x93, 0xB5, 0xE0, -0x91, 0xF1, 0x90, 0x93, 0xB0, 0xE0, 0x24, 0xB1, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xEF, -0xF0, 0x90, 0x93, 0xB0, 0xE0, 0x04, 0xF0, 0x80, 0xD2, 0x78, 0xB1, 0x7C, 0x93, 0x12, 0x9E, 0xE2, -0xEF, 0x70, 0x1C, 0x90, 0x93, 0xB6, 0xE0, 0x24, 0x08, 0xFF, 0x90, 0x93, 0xB5, 0xE0, 0x34, 0x00, -0xFE, 0xB1, 0xBC, 0xEF, 0x64, 0x01, 0x60, 0x07, 0x90, 0x01, 0xC7, 0x74, 0x22, 0xF1, 0xD7, 0x22, -0x24, 0x06, 0xFD, 0x91, 0xFE, 0xEF, 0x22, 0xF0, 0x90, 0x8F, 0x36, 0xE0, 0x44, 0x01, 0xF0, 0x22, -0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xFD, 0x81, 0xFE, 0x90, 0x93, 0xB7, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, -0x22, 0x90, 0x94, 0xD1, 0xE0, 0xFE, 0xA3, 0xE0, 0x22, 0x90, 0x8F, 0x2E, 0xE0, 0xC4, 0x13, 0x13, -0x54, 0x03, 0x22, 0x7F, 0xF4, 0x12, 0x4A, 0x84, 0xEF, 0x20, 0xE5, 0x0E, 0x7F, 0xF4, 0x12, 0x4A, -0x84, 0xEF, 0x7F, 0x01, 0x20, 0xE4, 0x05, 0x7F, 0x02, 0x22, 0x7F, 0x03, 0x22, 0x75, 0xE8, 0x03, -0x75, 0xA8, 0x85, 0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x48, 0x39, 0x90, 0x93, 0xA6, -0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x8D, 0x01, 0xE0, 0xFF, 0x60, 0xE9, 0xC2, 0xAF, 0x30, 0xE1, 0x06, -0x54, 0xFD, 0xF0, 0x12, 0x84, 0x32, 0x11, 0x6F, 0x30, 0xE2, 0x05, 0x54, 0xFB, 0xF0, 0x11, 0xAB, -0x11, 0x6F, 0x30, 0xE4, 0x0B, 0x54, 0xEF, 0xF0, 0x11, 0x79, 0xBF, 0x01, 0x03, 0x12, 0x59, 0xC5, -0x11, 0x6F, 0x30, 0xE7, 0x06, 0x54, 0x7F, 0xF0, 0x12, 0x50, 0xAD, 0xD2, 0xAF, 0x80, 0xC5, 0xD2, -0xAF, 0xC2, 0xAF, 0x90, 0x8D, 0x01, 0xE0, 0xFF, 0x22, 0xE4, 0x90, 0x95, 0x85, 0xF0, 0xA3, 0xF0, -0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x21, 0xC3, 0x90, 0x95, 0x86, 0xE0, 0x94, 0xD0, 0x90, 0x95, -0x85, 0xE0, 0x94, 0x07, 0x40, 0x0A, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x00, 0x22, -0x90, 0x95, 0x85, 0x12, 0x8E, 0x8D, 0x80, 0xD8, 0x7F, 0x01, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, -0xC0, 0xD0, 0xE4, 0xFF, 0x90, 0x8D, 0xF7, 0xE0, 0xFE, 0x90, 0x8D, 0xF6, 0xE0, 0xFD, 0xB5, 0x06, -0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x64, 0x01, 0x60, 0x24, 0xED, 0x12, 0x9F, 0x2A, -0xFA, 0x7B, 0x01, 0x11, 0xF5, 0x7F, 0x01, 0xEF, 0x60, 0x16, 0x90, 0x8D, 0xF6, 0xE0, 0x04, 0xF0, -0xE0, 0xB4, 0x0A, 0x02, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x8D, 0xF6, 0xF0, -0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x62, 0x12, -0x44, 0x12, 0x7F, 0x96, 0x7E, 0x02, 0x12, 0x8E, 0x46, 0xEF, 0x60, 0x42, 0x31, 0x54, 0xFE, 0x12, -0x9F, 0xE7, 0x90, 0x95, 0x65, 0xEF, 0xF0, 0xEE, 0xFF, 0x90, 0xFD, 0x11, 0xF0, 0x90, 0x95, 0x65, -0xE0, 0xFD, 0x90, 0x02, 0x94, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x95, 0x62, 0x12, 0x90, 0x52, 0x24, -0x02, 0xFF, 0xE4, 0x33, 0xFE, 0x12, 0x8E, 0xB4, 0x90, 0x95, 0x65, 0xE0, 0x24, 0x18, 0xFF, 0x90, -0x95, 0x62, 0x12, 0x44, 0x09, 0x12, 0x8F, 0xE6, 0x90, 0x02, 0x96, 0x74, 0x01, 0xF0, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0xF0, 0x90, 0x01, 0x17, 0xE0, 0xFE, 0x90, 0x01, 0x16, 0xE0, 0x7C, 0x00, 0x24, -0x00, 0xFF, 0xEC, 0x3E, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x2A, 0xEC, -0x12, 0xA0, 0x37, 0xAA, 0x07, 0x90, 0x95, 0x31, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x12, -0x9F, 0x75, 0xEA, 0x24, 0xEF, 0x60, 0x3B, 0x24, 0xD7, 0x70, 0x02, 0x41, 0xC8, 0x24, 0x3A, 0x60, -0x02, 0x61, 0x00, 0xD1, 0x5E, 0x24, 0x0A, 0xD1, 0x6D, 0xED, 0xF0, 0xFE, 0x71, 0x3F, 0xB1, 0x7A, -0xE4, 0xF0, 0xFE, 0x74, 0x00, 0x2F, 0xF1, 0xC8, 0x7D, 0x14, 0x71, 0x18, 0x7B, 0x00, 0x7A, 0x00, -0x79, 0x00, 0x71, 0x23, 0x90, 0xAC, 0x6A, 0x12, 0x08, 0x6D, 0x7D, 0x14, 0x7C, 0x00, 0xE4, 0xFF, -0x41, 0xC3, 0x90, 0x95, 0x2A, 0xE4, 0x75, 0xF0, 0x14, 0x12, 0x08, 0xD6, 0x90, 0x95, 0x2A, 0xA3, -0xE0, 0xFB, 0xFF, 0x24, 0x06, 0xFC, 0xD1, 0x6E, 0xCC, 0xF0, 0x90, 0x95, 0x35, 0xA3, 0xE0, 0xFE, -0x71, 0x3F, 0xB1, 0x7A, 0xE4, 0xF1, 0xA3, 0xE0, 0xFE, 0xA9, 0x03, 0x74, 0x05, 0x29, 0xF5, 0x82, -0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x31, 0x5C, 0xFE, 0x90, 0x95, 0x2F, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, -0x95, 0x2A, 0xE0, 0xFC, 0xA3, 0xE0, 0x2F, 0xFF, 0xEC, 0x3E, 0xFE, 0xD3, 0xEF, 0x94, 0x00, 0xEE, -0x94, 0x01, 0x90, 0x95, 0x2A, 0x40, 0x6A, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE9, 0x7C, 0x00, 0x24, -0x00, 0xF9, 0xEC, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xC3, 0xE4, 0x9F, 0xFD, 0x74, 0x01, 0x9E, 0xFC, -0x71, 0x1A, 0x90, 0x95, 0x2C, 0xE0, 0x24, 0x01, 0xFF, 0xE4, 0x33, 0xA2, 0xE7, 0x13, 0xEF, 0x13, -0x90, 0xFD, 0x10, 0xF0, 0xD1, 0x90, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0x7B, 0x01, -0x7A, 0xFC, 0x79, 0x00, 0x90, 0x95, 0x2A, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0xE4, 0x9F, 0xFF, -0x74, 0x01, 0x9E, 0xFE, 0xD1, 0x65, 0xC3, 0x9F, 0xFD, 0xEC, 0x9E, 0xFC, 0x12, 0x26, 0x4E, 0xD0, -0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x42, 0x90, 0x71, 0x1D, 0x12, 0x9F, 0x75, 0x80, -0x0D, 0xA3, 0xE0, 0x7E, 0x00, 0x24, 0x00, 0xF1, 0xC8, 0xD1, 0x65, 0xFD, 0x71, 0x1A, 0x90, 0x95, -0x2A, 0x74, 0xFF, 0x75, 0xF0, 0xEC, 0x12, 0x08, 0xD6, 0xD1, 0x5E, 0x7E, 0x00, 0x24, 0x0C, 0xF9, -0xEE, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xC0, 0x02, 0xC0, 0x01, 0x74, 0x10, 0x2F, 0xF9, 0xEE, 0x34, -0xFC, 0xFA, 0x71, 0x23, 0x90, 0xAC, 0x6A, 0x12, 0x08, 0x6D, 0xD1, 0x65, 0xFD, 0xD0, 0x01, 0xD0, -0x02, 0x7F, 0x11, 0x12, 0x1B, 0xAC, 0x80, 0x30, 0xD1, 0x5E, 0x24, 0x2A, 0xD1, 0x6D, 0xED, 0xF0, -0xFE, 0x71, 0x3F, 0xB1, 0x7A, 0xE4, 0xF0, 0x12, 0x99, 0x5C, 0x7D, 0x48, 0x71, 0x18, 0x71, 0x29, -0xD1, 0x8B, 0x12, 0x42, 0x90, 0xE4, 0xFD, 0xFC, 0x71, 0x1D, 0x71, 0x29, 0xD1, 0x8B, 0x12, 0x42, -0x90, 0x71, 0x1D, 0x71, 0x29, 0x12, 0x08, 0x3A, 0x90, 0x95, 0x2D, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, -0x90, 0x95, 0x2D, 0x12, 0xA0, 0x2F, 0x90, 0x95, 0x35, 0xA3, 0xE0, 0xFE, 0x71, 0x3F, 0xEF, 0xB1, -0x7B, 0xED, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7C, 0x00, 0x12, 0x26, 0x4E, 0x90, 0x95, 0x31, -0x02, 0x08, 0x6D, 0x90, 0xAC, 0x67, 0x12, 0x44, 0x12, 0x90, 0x95, 0x31, 0x02, 0x43, 0xE5, 0x12, -0x42, 0x90, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, 0x93, 0xAB, 0xA3, 0xE0, 0x24, -0x00, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, -0xE4, 0x90, 0x93, 0xAB, 0xF0, 0xA3, 0xF0, 0x90, 0x93, 0x87, 0xE0, 0xFF, 0xD1, 0x4A, 0x7E, 0x00, -0x90, 0x93, 0xAB, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x71, 0x3F, 0xE0, 0x90, 0x91, 0x33, 0xF0, 0xF1, -0xE1, 0x90, 0x93, 0xAB, 0xA3, 0xE0, 0x24, 0x02, 0xF1, 0xAF, 0xFF, 0xE4, 0xFC, 0xFD, 0x78, 0x10, -0x12, 0x08, 0x5A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xD1, 0xA3, 0xB1, 0x60, 0x78, -0x18, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x42, 0x90, 0xC0, -0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xD1, 0x96, 0xB1, 0x60, 0x78, 0x08, 0x12, 0x08, 0x5A, -0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x71, 0x2F, 0xB1, 0x62, 0x12, 0x42, 0x90, 0x90, -0x91, 0x37, 0xB1, 0x47, 0x78, 0x10, 0x12, 0x08, 0x5A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, -0x07, 0xD1, 0xA3, 0xB1, 0x60, 0x78, 0x18, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, -0xD0, 0x00, 0x12, 0x42, 0x90, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xD1, 0x96, 0xB1, -0x60, 0x78, 0x08, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x71, 0x2F, -0xB1, 0x62, 0x12, 0x42, 0x90, 0x90, 0x91, 0x3B, 0xB1, 0x47, 0x78, 0x10, 0x12, 0x08, 0x5A, 0xC0, -0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xD1, 0xA3, 0xB1, 0x60, 0x78, 0x18, 0x12, 0x08, 0x5A, -0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x42, 0x90, 0xC0, 0x04, 0xC0, 0x05, 0xC0, -0x06, 0xC0, 0x07, 0xD1, 0x96, 0xB1, 0x60, 0x78, 0x08, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, -0xD0, 0x01, 0xD0, 0x00, 0x71, 0x2F, 0xB1, 0x62, 0x12, 0x42, 0x90, 0x90, 0x91, 0x3F, 0x12, 0x08, -0x6D, 0xF1, 0xE1, 0xE4, 0x90, 0x93, 0xAD, 0xF0, 0xD1, 0x80, 0x71, 0x3F, 0xE0, 0xFF, 0x12, 0x9F, -0x4A, 0xEF, 0xF0, 0xB1, 0x73, 0xE0, 0xB4, 0x10, 0xEF, 0xD1, 0x76, 0xE4, 0x90, 0x93, 0xAD, 0xF0, -0xD1, 0x80, 0x71, 0x3F, 0xE0, 0xFF, 0x74, 0x53, 0x2E, 0x12, 0x9F, 0xC8, 0xEF, 0xF0, 0xB1, 0x73, -0xE0, 0xB4, 0x10, 0xEC, 0xD1, 0x76, 0xE4, 0x90, 0x93, 0xAD, 0xF0, 0xD1, 0x80, 0x71, 0x3F, 0xE0, -0xFF, 0x74, 0x63, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x91, 0xF5, 0x83, 0xEF, 0xF0, 0xB1, 0x73, 0xE0, -0xB4, 0x10, 0xE8, 0xD1, 0x76, 0x90, 0x93, 0x87, 0xE0, 0x04, 0x90, 0x93, 0xAF, 0xF0, 0xE4, 0x90, -0x93, 0xAE, 0xF0, 0x90, 0x91, 0x33, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x24, 0x01, 0xFF, 0xE4, 0x33, -0xFE, 0x90, 0x93, 0xAE, 0xE0, 0xFD, 0xC3, 0x12, 0x9F, 0xC0, 0x98, 0x50, 0x63, 0xA3, 0xE0, 0x2D, -0xF0, 0xD1, 0x42, 0xE4, 0xF1, 0xF4, 0x90, 0x93, 0xAD, 0xE0, 0xFD, 0xC3, 0x94, 0x04, 0x50, 0x48, -0xA3, 0xE0, 0x75, 0xF0, 0x04, 0xA4, 0x7C, 0x00, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0xEF, 0x78, -0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x24, 0x73, 0xF9, 0x74, 0x91, 0x3E, 0xFA, 0x7B, -0x01, 0xC0, 0x03, 0xC0, 0x01, 0x90, 0x93, 0xAB, 0xA3, 0xE0, 0x24, 0x00, 0xF9, 0xE4, 0x34, 0xFC, -0x8B, 0x40, 0xF5, 0x41, 0x89, 0x42, 0x75, 0x43, 0x20, 0xD0, 0x01, 0xD0, 0x03, 0x12, 0x57, 0x5A, -0xE4, 0x75, 0xF0, 0x20, 0xB1, 0x70, 0x80, 0xAE, 0x90, 0x93, 0xAE, 0xE0, 0x04, 0xF0, 0x80, 0x83, -0xE4, 0x90, 0x93, 0xAD, 0xF0, 0xE4, 0xFF, 0x0F, 0xEF, 0xB4, 0x20, 0xFB, 0xB1, 0x73, 0xE0, 0xB4, -0x10, 0xF3, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x08, 0x6D, 0x90, 0x93, 0xAB, 0xE4, 0x75, 0xF0, -0x04, 0x12, 0x08, 0xD6, 0x90, 0x93, 0xAB, 0xA3, 0xE0, 0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0xFC, -0xF5, 0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x22, 0x90, 0x93, 0xD0, 0xE4, 0x75, 0xF0, 0x04, -0x12, 0x08, 0xD6, 0x90, 0x93, 0xAD, 0xE0, 0x04, 0xF0, 0x22, 0xE4, 0xF0, 0x74, 0x01, 0x2E, 0xF5, -0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90, 0x93, 0x84, 0xD1, 0x42, 0xEF, 0xF0, 0xE0, 0xFE, -0x24, 0x28, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFF, 0x74, 0x29, 0x2E, 0x12, 0x7E, -0xF4, 0xFD, 0x90, 0x93, 0xAB, 0xE0, 0x24, 0x2C, 0x12, 0x8B, 0xA4, 0x90, 0x93, 0xAB, 0xE0, 0x2F, -0x24, 0x30, 0xA3, 0xF0, 0xE0, 0xFD, 0x24, 0x04, 0xF1, 0xA7, 0xE0, 0xFE, 0x74, 0x05, 0x2D, 0xF5, -0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x31, 0x5C, 0x90, 0x90, 0xE7, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, -0x93, 0xAC, 0xE0, 0x24, 0x0C, 0xF9, 0xE4, 0x34, 0xFC, 0x12, 0x83, 0xD0, 0x7A, 0x90, 0x79, 0xE9, -0x12, 0x35, 0x26, 0x90, 0x93, 0xAC, 0xE0, 0x24, 0x14, 0xF0, 0xE0, 0xFD, 0x24, 0x01, 0xB1, 0x7F, -0xE0, 0xFE, 0x74, 0x00, 0x2D, 0x71, 0x41, 0x31, 0x5C, 0x90, 0x90, 0xED, 0xF0, 0xA3, 0xEF, 0xF0, -0x90, 0x93, 0x85, 0xD1, 0x42, 0xEF, 0xF0, 0x90, 0x90, 0xE3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x4E, -0x60, 0x14, 0x90, 0x93, 0xAB, 0xE0, 0x12, 0x83, 0xC4, 0x89, 0x42, 0x8F, 0x43, 0x7B, 0x01, 0x7A, -0x90, 0x79, 0xF1, 0x12, 0x35, 0x26, 0x90, 0x93, 0x86, 0xD1, 0x42, 0xEF, 0xF0, 0x12, 0x83, 0xC4, -0x89, 0x42, 0x90, 0x90, 0xE5, 0xA3, 0xE0, 0xF5, 0x43, 0x7B, 0x01, 0x7A, 0x91, 0x79, 0x11, 0x02, -0x35, 0x26, 0xE0, 0xFF, 0xD1, 0x4A, 0x90, 0x93, 0xAB, 0x22, 0xE4, 0xFE, 0xEF, 0xC3, 0x13, 0xFD, -0xEF, 0x30, 0xE0, 0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED, 0xF0, 0xAF, 0x06, 0x22, 0x90, 0x95, -0x2A, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x95, 0x2F, 0xE0, 0xFC, 0xA3, 0xE0, 0x22, 0xFD, 0xE4, 0x33, -0x90, 0x95, 0x35, 0xF0, 0xA3, 0x22, 0x90, 0x93, 0xAB, 0xE4, 0x75, 0xF0, 0x10, 0x02, 0x08, 0xD6, -0x90, 0x93, 0xAB, 0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0xFE, 0x2F, 0x22, 0x78, 0x10, 0x12, 0x08, 0x47, -0x90, 0x95, 0x31, 0x02, 0x43, 0xF1, 0x90, 0x93, 0xAB, 0xA3, 0xE0, 0x24, 0x01, 0xF5, 0x82, 0xE4, -0x34, 0xFC, 0x22, 0x90, 0x93, 0xAB, 0xA3, 0xE0, 0x24, 0x03, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0x22, -0x90, 0x8D, 0xFD, 0xE0, 0xFF, 0xD1, 0x4A, 0x74, 0x00, 0x2F, 0x71, 0x41, 0xE0, 0x90, 0x94, 0xB7, -0xF0, 0x74, 0x01, 0x2F, 0xB1, 0x7F, 0xE0, 0x90, 0x94, 0xB8, 0xF0, 0x74, 0x02, 0x2F, 0xF1, 0xAF, -0x90, 0x94, 0xB9, 0xF0, 0x74, 0x03, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x90, -0x94, 0xBA, 0xF1, 0xA3, 0xE0, 0x90, 0x94, 0xBB, 0xF0, 0x74, 0x05, 0x2F, 0xF5, 0x82, 0xE4, 0x34, -0xFC, 0xF5, 0x83, 0xE0, 0x90, 0x94, 0xBC, 0xF0, 0x74, 0x06, 0x2F, 0xF1, 0xD0, 0x90, 0x94, 0xBD, -0xF0, 0x74, 0x07, 0x2F, 0xF1, 0xC0, 0xE0, 0x90, 0x94, 0xBE, 0xF0, 0x74, 0x08, 0x2F, 0xF1, 0xB8, -0xE0, 0x90, 0x94, 0xBF, 0xF0, 0x22, 0xE4, 0xFD, 0xFC, 0x90, 0x93, 0x83, 0xF1, 0xEB, 0xAB, 0x05, -0x74, 0x01, 0x2B, 0xB1, 0x7F, 0xE0, 0xFE, 0x74, 0x00, 0x2B, 0x71, 0x41, 0x12, 0x9E, 0xFC, 0x90, -0x90, 0xDD, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x03, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, -0xE0, 0xFE, 0x74, 0x02, 0x2B, 0xF1, 0xAF, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x90, 0x90, 0xDF, 0xF0, -0xA3, 0xEF, 0xF0, 0x74, 0x05, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, -0x04, 0x2B, 0xF1, 0xA7, 0xE0, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x90, 0x90, 0xE1, 0xF0, 0xA3, 0xEF, -0xF0, 0x74, 0x07, 0x2B, 0xF1, 0xC0, 0xE0, 0xFE, 0x74, 0x06, 0x2B, 0xF1, 0xD0, 0x24, 0x00, 0xFF, -0xEA, 0x3E, 0x90, 0x90, 0xE3, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x09, 0x2B, 0x12, 0x7F, 0x01, 0xFE, -0x74, 0x08, 0x2B, 0xF1, 0xB8, 0xE0, 0x24, 0x00, 0xFF, 0xEC, 0x3E, 0x90, 0x90, 0xE5, 0xF0, 0xA3, -0xEF, 0xF0, 0x22, 0xF0, 0x74, 0x04, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, -0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, -0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF9, 0xEE, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, -0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xEF, 0x60, 0x04, 0xF1, 0x16, 0xB1, 0x87, -0x22, 0x90, 0x93, 0xAB, 0xE4, 0x75, 0xF0, 0x04, 0x02, 0x08, 0xD6, 0xE0, 0xFF, 0xD1, 0x4A, 0x7C, -0x00, 0xAD, 0x07, 0x22, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0xC0, 0xE0, 0xC0, 0x83, -0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, 0xFC, 0x90, 0x01, 0xC4, -0xED, 0xF0, 0x74, 0x67, 0x11, 0x23, 0xD0, 0x07, 0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, -0xD0, 0xE0, 0x32, 0xFF, 0xA3, 0xF0, 0xED, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, -0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, -0x30, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x68, 0x11, 0x23, 0xD0, 0x07, 0xD0, 0x05, 0xD0, 0xD0, -0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, -0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, -0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0x57, 0xF0, 0x74, 0x68, 0xA3, 0xF0, 0x12, 0x4B, -0xB0, 0xE5, 0x14, 0x30, 0xE7, 0x03, 0x12, 0x4F, 0xDF, 0x74, 0x57, 0x04, 0x90, 0x01, 0xC4, 0xF0, -0x74, 0x68, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, -0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0xC0, -0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, -0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, -0xAF, 0xF0, 0x74, 0x68, 0xA3, 0xF0, 0x12, 0x92, 0x06, 0xE5, 0x19, 0x30, 0xE3, 0x02, 0x71, 0x26, -0xE5, 0x19, 0x30, 0xE4, 0x02, 0x31, 0xEB, 0xE5, 0x19, 0x30, 0xE5, 0x03, 0x12, 0x92, 0x63, 0xE5, -0x1B, 0x30, 0xE0, 0x02, 0x31, 0x50, 0xE5, 0x1B, 0x30, 0xE1, 0x02, 0x91, 0xA1, 0xE5, 0x1B, 0x30, -0xE2, 0x02, 0x71, 0xEF, 0xE5, 0x1B, 0x30, 0xE3, 0x02, 0x71, 0x32, 0xE5, 0x1B, 0x30, 0xE4, 0x02, -0x71, 0x4D, 0xE5, 0x1B, 0x30, 0xE5, 0x03, 0x12, 0x7A, 0x46, 0xE5, 0x1B, 0x30, 0xE6, 0x03, 0x12, -0x79, 0x6E, 0xE5, 0x1C, 0x30, 0xE1, 0x03, 0x12, 0x92, 0x9F, 0x74, 0xAF, 0x04, 0x90, 0x01, 0xC4, -0xF0, 0x74, 0x68, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, -0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, -0xE4, 0xF5, 0x58, 0x90, 0x8E, 0x84, 0xE0, 0x70, 0x02, 0x21, 0xE0, 0x71, 0x46, 0x60, 0x02, 0x21, -0xE0, 0x90, 0x8E, 0x80, 0xE0, 0x30, 0xE0, 0x17, 0x12, 0x8D, 0x12, 0xFD, 0xED, 0x78, 0x02, 0xCE, -0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0x8E, 0xB9, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, -0x8E, 0x82, 0xE0, 0xC4, 0x54, 0x0F, 0x60, 0x22, 0x24, 0xFE, 0x60, 0x03, 0x04, 0x70, 0x1E, 0x90, -0x8E, 0x8B, 0xE0, 0x14, 0xF0, 0xE0, 0xFF, 0x60, 0x06, 0x90, 0x8E, 0x8D, 0xE0, 0x60, 0x0E, 0xEF, -0x70, 0x08, 0x90, 0x8E, 0x8A, 0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x75, 0x58, 0x01, 0xE5, 0x58, 0x60, -0x2F, 0x12, 0xA0, 0x17, 0x90, 0x8E, 0x8D, 0xE0, 0x60, 0x03, 0xB4, 0x01, 0x04, 0x31, 0xE1, 0x80, -0x08, 0x31, 0xE1, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, 0x90, 0x8E, 0x8C, 0xE0, 0x2F, 0xF1, -0x09, 0x7E, 0x01, 0x12, 0x50, 0x02, 0x90, 0x8E, 0x87, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x51, 0xE7, -0x22, 0xE4, 0x90, 0x95, 0x43, 0xF0, 0x90, 0x8E, 0x8D, 0xE0, 0x22, 0x31, 0xFE, 0x7F, 0x02, 0x8F, -0x59, 0x7F, 0x02, 0x12, 0x48, 0x12, 0x90, 0x8D, 0x01, 0xE0, 0x45, 0x59, 0xF0, 0x22, 0x90, 0x01, -0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x95, 0x7D, 0xF0, 0x90, 0x95, 0x7D, 0xE0, 0xFD, 0x70, 0x02, 0x41, -0xFB, 0x90, 0x8D, 0x5E, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, -0xFF, 0x90, 0x8D, 0x5F, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, -0x08, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x95, 0x7B, 0xE0, 0xFF, 0x12, 0xA0, -0x1F, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0x41, -0xDD, 0xE4, 0x90, 0x95, 0x7E, 0xF0, 0x90, 0x95, 0x7E, 0xE0, 0xF9, 0xC3, 0x94, 0x04, 0x50, 0x31, -0x51, 0xFC, 0xA4, 0xFF, 0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xD0, -0x71, 0x14, 0x90, 0x8D, 0x0E, 0x71, 0x04, 0x51, 0xFC, 0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, -0x74, 0xF0, 0x71, 0x14, 0x90, 0x8D, 0x12, 0x71, 0x04, 0x90, 0x95, 0x7E, 0xE0, 0x04, 0xF0, 0x80, -0xC5, 0x90, 0x95, 0x7D, 0xE0, 0xFF, 0x90, 0x95, 0x7B, 0x12, 0x4B, 0x52, 0x80, 0x02, 0xC3, 0x33, -0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x95, 0x7D, 0xF0, 0x90, 0x95, 0x7B, 0xE0, 0xFF, 0x74, 0x01, 0xA8, -0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x95, 0x7B, 0xE0, -0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0x90, 0x8D, 0x5F, 0x12, 0x84, 0x2B, 0xB4, 0x0A, 0x02, 0x7F, -0x01, 0xEF, 0x70, 0x02, 0x41, 0x08, 0xE4, 0x90, 0x8D, 0x5F, 0xF0, 0x41, 0x08, 0x90, 0x01, 0xC0, -0xE0, 0x44, 0x02, 0xF0, 0x90, 0x95, 0x7B, 0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A, 0xF0, 0x51, 0xFC, -0x90, 0x01, 0xD0, 0x12, 0x43, 0xFD, 0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, 0x90, 0x95, 0x7B, 0xE0, -0x75, 0xF0, 0x04, 0x22, 0x12, 0x43, 0xFD, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5, -0x83, 0xEF, 0xF0, 0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x8D, -0x5F, 0xE0, 0x75, 0xF0, 0x08, 0x22, 0x90, 0x8F, 0x2E, 0xE0, 0x30, 0xE0, 0x04, 0x7F, 0x10, 0x31, -0xEF, 0x22, 0x71, 0x46, 0x70, 0x0F, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x09, 0x71, 0x69, 0xD1, 0xFF, -0x7E, 0x01, 0x12, 0x50, 0x02, 0x22, 0x90, 0x8D, 0xFF, 0xE0, 0x64, 0x01, 0x22, 0x71, 0x46, 0x70, -0x17, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x11, 0x71, 0x69, 0xF0, 0x90, 0x8E, 0x80, 0xE0, 0x12, 0x9E, -0xD7, 0x54, 0x07, 0x70, 0x03, 0x12, 0x79, 0x32, 0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, -0x3C, 0x74, 0x02, 0x22, 0x71, 0x46, 0x70, 0x76, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x70, 0x90, 0x8E, -0x82, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70, 0x26, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x8E, -0x8B, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x04, 0x90, 0x8E, 0x8A, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, 0x08, -0x90, 0x8E, 0x8A, 0xE0, 0xFE, 0xFF, 0x80, 0x03, 0xEF, 0x04, 0xFF, 0x90, 0x8E, 0x8B, 0xEF, 0xF0, -0x90, 0x8E, 0x80, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0x88, 0xC2, 0x12, 0xA0, 0x0F, 0xE4, 0x90, 0x8E, -0x8D, 0xF0, 0x12, 0x7F, 0xF9, 0x71, 0x69, 0x12, 0x9E, 0xD9, 0x54, 0xEF, 0xF0, 0x90, 0x8E, 0x82, -0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x03, 0x12, 0x79, 0x8C, 0x12, 0x9E, -0xBA, 0x30, 0xE0, 0x0A, 0x12, 0xA0, 0x07, 0xB5, 0x07, 0x04, 0xD1, 0x3A, 0x91, 0x1C, 0x22, 0x90, -0x93, 0x93, 0xE0, 0x04, 0xF0, 0x90, 0x8E, 0x87, 0xE0, 0x64, 0x02, 0x60, 0x18, 0x71, 0x74, 0x12, -0x9E, 0xBA, 0x30, 0xE0, 0x10, 0x12, 0xA0, 0x07, 0x6F, 0x70, 0x0A, 0xD1, 0x3A, 0x91, 0x16, 0x90, -0x8E, 0x8B, 0xE0, 0x14, 0xF0, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0x91, 0x20, 0x7D, 0x01, 0x7F, 0x02, -0x74, 0x15, 0x12, 0xA0, 0x4F, 0xFE, 0xF6, 0x74, 0x30, 0xD1, 0xB0, 0xF0, 0x22, 0xEF, 0x70, 0x36, -0x7D, 0x78, 0x7F, 0x02, 0x91, 0x20, 0x7D, 0x02, 0x7F, 0x03, 0x91, 0x20, 0x7D, 0xC8, 0x7F, 0x02, -0xD1, 0xA3, 0x71, 0x69, 0xF0, 0x90, 0x8D, 0xFF, 0xE0, 0x70, 0x0A, 0xB1, 0x7E, 0x54, 0xBF, 0xF0, -0x54, 0x7F, 0xF0, 0x80, 0x07, 0x7D, 0x01, 0x7F, 0x0C, 0x12, 0x51, 0xEB, 0xB1, 0x82, 0x90, 0x06, -0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22, 0x90, 0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02, 0xF0, -0x7D, 0x78, 0xFF, 0xB1, 0xA1, 0x7D, 0x02, 0x7F, 0x03, 0xB1, 0xA1, 0x90, 0x06, 0x0A, 0xE0, 0x44, -0x07, 0xF0, 0x12, 0x7F, 0xF9, 0x90, 0x8D, 0xFF, 0xE0, 0xB4, 0x01, 0x11, 0x12, 0x9F, 0xFF, 0x90, -0x8E, 0x87, 0xE0, 0x20, 0xE2, 0x0A, 0x7D, 0x01, 0x7F, 0x04, 0x02, 0x51, 0xEB, 0x12, 0xA0, 0x0F, -0x22, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x5F, 0x90, 0x8E, 0x80, 0xE0, 0x30, 0xE0, 0x1D, 0x90, 0x8E, -0x98, 0xE0, 0x04, 0xF0, 0x12, 0x8D, 0x12, 0xFD, 0xED, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, -0xD8, 0xF9, 0xFF, 0x90, 0x8E, 0xB5, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x8E, 0x81, 0x12, 0x9E, -0xF4, 0x30, 0xE0, 0x0C, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x05, 0x91, 0x16, 0x12, 0x9F, 0xA6, -0x90, 0x95, 0x7F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x08, 0xD6, 0xC3, 0x90, 0x95, 0x80, 0xE0, 0x94, -0x80, 0x90, 0x95, 0x7F, 0xE0, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, -0xFE, 0xF0, 0xE0, 0x44, 0x01, 0xF0, 0x12, 0x99, 0x9B, 0xF1, 0x4B, 0xE4, 0x90, 0x93, 0x8C, 0xF0, -0xB1, 0x6B, 0x12, 0x5F, 0xF9, 0x30, 0xE0, 0x52, 0x90, 0x90, 0xDD, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, -0x7C, 0x00, 0x7D, 0x64, 0x12, 0x07, 0x15, 0x90, 0x91, 0x31, 0xE0, 0x6E, 0x70, 0x03, 0xA3, 0xE0, -0x6F, 0x60, 0x0A, 0x90, 0x91, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x08, 0xD6, 0x90, 0x90, 0xE1, -0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x90, 0xEF, 0xE0, 0xB5, 0x06, 0x14, 0xA3, 0xE0, 0xB5, 0x07, -0x0F, 0xEF, 0x4E, 0x60, 0x0B, 0x90, 0x01, 0xC7, 0x74, 0x31, 0xF0, 0x7F, 0x01, 0x02, 0x73, 0xCF, -0x12, 0x8A, 0xFF, 0xE4, 0x90, 0x91, 0x31, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x8F, 0x2A, 0xE0, 0x30, -0xE0, 0x0B, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x04, 0x91, 0x16, 0xD1, 0x9A, 0x22, 0xF1, 0x13, -0xB1, 0x8A, 0x90, 0x8E, 0x80, 0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x12, 0x8A, 0xEF, 0x12, 0x57, 0xF3, -0x7D, 0x0C, 0x7F, 0x01, 0x02, 0x53, 0xDC, 0x7D, 0x02, 0x7F, 0x02, 0xB1, 0xA1, 0x7D, 0x01, 0x7F, -0x02, 0x74, 0x15, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x30, 0xD1, 0xB0, 0xF0, 0x22, 0xD3, -0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x92, 0xEF, 0xF0, 0x54, 0x01, 0xFF, 0x90, 0x8F, -0x2A, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x12, 0x9E, 0xF1, 0x30, 0xE0, 0x39, 0x12, 0x9F, 0x5F, 0x60, -0x10, 0x12, 0x9F, 0x55, 0x40, 0x0B, 0xE4, 0x7F, 0x0A, 0xFE, 0xFD, 0xFC, 0x90, 0x91, 0x3F, 0x80, -0x09, 0xE4, 0x7F, 0x0A, 0xFE, 0xFD, 0xFC, 0x90, 0x91, 0x37, 0x12, 0x43, 0xF1, 0x12, 0x42, 0x9D, -0xC0, 0x07, 0x90, 0x8F, 0x2C, 0xE0, 0xFB, 0xE4, 0xFA, 0xF9, 0xF8, 0xD0, 0x07, 0x12, 0x43, 0x28, -0x90, 0x8F, 0x2D, 0xEF, 0xF0, 0x90, 0x95, 0x92, 0xE0, 0x64, 0x01, 0x70, 0x1F, 0x90, 0x01, 0x53, -0xF0, 0x90, 0x8F, 0x2C, 0xE0, 0x60, 0x0A, 0x7D, 0x10, 0x7F, 0x03, 0xD1, 0x49, 0xD1, 0x9A, 0x80, -0x14, 0xD1, 0xBA, 0xD1, 0xA3, 0x91, 0x16, 0x12, 0x9B, 0x76, 0x80, 0x09, 0xD1, 0xBA, 0xD1, 0x49, -0xB1, 0x97, 0x12, 0x9B, 0x87, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xEF, 0x14, 0x90, 0x05, 0x73, 0xF0, -0x90, 0x01, 0x3F, 0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, 0x74, 0x1D, 0x2F, 0xF8, 0xE6, 0x4D, 0xD1, -0xAC, 0xF0, 0x22, 0x90, 0x8F, 0x2A, 0xE0, 0x30, 0xE0, 0x3F, 0xD1, 0x9A, 0x90, 0x8F, 0x2D, 0xE0, -0x60, 0x05, 0x14, 0xF0, 0x02, 0x9B, 0x76, 0x90, 0x8F, 0x2B, 0xE0, 0x14, 0x90, 0x8F, 0x2D, 0xF0, -0x90, 0x05, 0x73, 0x74, 0x01, 0xF0, 0xE4, 0xFF, 0xB1, 0xAF, 0xB1, 0x97, 0x90, 0x8D, 0xFB, 0xE0, -0xFF, 0x20, 0xE0, 0x08, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x0D, 0x90, 0x95, 0x46, 0x12, -0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x12, 0x50, 0x34, 0x22, 0x90, 0x8F, 0x2C, 0xE0, 0x90, 0x05, -0x73, 0xF0, 0x22, 0x74, 0x1D, 0x12, 0xA0, 0x4F, 0xD1, 0xAC, 0xF0, 0x22, 0xFE, 0xF6, 0x74, 0x38, -0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0xEE, 0x22, 0x90, 0x01, 0x53, 0x74, 0x03, 0xF0, -0x7D, 0x10, 0xFF, 0x22, 0xD1, 0xD1, 0x12, 0x9F, 0xA6, 0x7D, 0x02, 0x7F, 0x02, 0xB1, 0xA1, 0x80, -0x82, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x27, 0x71, 0x46, 0x70, 0x23, 0x90, 0x8E, 0x8B, 0xF0, 0x04, -0x60, 0x1C, 0x12, 0xA0, 0x17, 0xE4, 0x90, 0x95, 0x43, 0xF0, 0x90, 0x8E, 0x8C, 0xF1, 0x08, 0x7E, -0x01, 0x12, 0x50, 0x02, 0x90, 0x8E, 0x87, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x51, 0xE7, 0x22, 0xF0, -0xE4, 0x90, 0x95, 0x43, 0xF0, 0x90, 0x8F, 0x24, 0xE0, 0x90, 0x95, 0x44, 0xF0, 0xE4, 0xFB, 0xFD, -0x7F, 0x54, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x02, -0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, 0xF0, 0x90, 0x06, 0xB4, -0x74, 0x86, 0xF0, 0x12, 0x9E, 0xC4, 0xE4, 0xFD, 0x12, 0x49, 0x53, 0x12, 0x4B, 0xAA, 0x44, 0x01, -0xFD, 0x7F, 0x02, 0x12, 0x49, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x93, 0x89, 0xE0, 0x30, -0xE0, 0x34, 0x71, 0x46, 0x70, 0x30, 0x90, 0x95, 0x8E, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x0B, -0x90, 0x93, 0x8B, 0xE0, 0x04, 0xF0, 0xE4, 0x90, 0x95, 0x8E, 0xF0, 0x90, 0x93, 0x8B, 0xE0, 0xFF, -0x90, 0x93, 0x8A, 0xE0, 0xD3, 0x9F, 0x50, 0x0E, 0x90, 0x93, 0x8C, 0xE0, 0x70, 0x08, 0xE4, 0x90, -0x93, 0x8B, 0xF0, 0x12, 0x84, 0x12, 0x22, 0xEF, 0x60, 0x41, 0x90, 0x93, 0x79, 0xE0, 0xFF, 0x60, -0x03, 0x12, 0x83, 0xDD, 0x90, 0x01, 0xC7, 0xE4, 0x12, 0x61, 0x53, 0x12, 0x9F, 0xB8, 0x90, 0x06, -0x09, 0xE0, 0x54, 0xFE, 0xF0, 0x7D, 0x35, 0x7F, 0xFF, 0x12, 0x54, 0x51, 0x12, 0x4B, 0x5A, 0x12, -0x9F, 0xF7, 0x12, 0x93, 0xB0, 0x12, 0x99, 0x75, 0xF1, 0x13, 0x12, 0x57, 0xF3, 0x12, 0x90, 0xAF, -0x90, 0x01, 0x34, 0x74, 0x08, 0xF0, 0xFD, 0xE4, 0xFF, 0xA1, 0xA1, 0x7D, 0x08, 0xE4, 0xFF, 0x91, -0x20, 0x90, 0x06, 0x90, 0xE0, 0x54, 0xF0, 0xF0, 0x12, 0x9F, 0xEF, 0x12, 0x91, 0x02, 0x12, 0x73, -0x82, 0x7E, 0x00, 0x7F, 0x1F, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x2E, 0x12, 0x08, 0xAA, -0x90, 0x06, 0x90, 0xE0, 0x44, 0x20, 0xF0, 0x12, 0x91, 0x27, 0x12, 0x73, 0x92, 0x90, 0x8D, 0x06, -0xE0, 0xFF, 0x64, 0x02, 0x70, 0x2A, 0x11, 0xC3, 0x30, 0xE0, 0x02, 0x7E, 0x01, 0x90, 0x8F, 0x4C, -0x11, 0xC1, 0x30, 0xE1, 0x02, 0x7E, 0x01, 0x90, 0x8F, 0x4A, 0x11, 0xC1, 0x30, 0xE2, 0x02, 0x7E, -0x01, 0x90, 0x8F, 0x4B, 0xEE, 0xF0, 0x90, 0xFD, 0x80, 0xE0, 0x90, 0x02, 0xFB, 0xF0, 0x80, 0x4A, -0xEF, 0x64, 0x01, 0x70, 0x1D, 0x11, 0xBA, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0x8F, 0x4C, 0x11, -0xB8, 0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, 0x8F, 0x4A, 0x11, 0xB8, 0x30, 0xE2, 0x02, 0x7F, 0x01, -0x80, 0x23, 0x90, 0x8D, 0x06, 0xE0, 0x64, 0x03, 0x70, 0x20, 0x11, 0xB1, 0x30, 0xE0, 0x02, 0x7F, -0x01, 0x90, 0x8F, 0x4C, 0x11, 0xAF, 0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, 0x8F, 0x4A, 0x11, 0xAF, -0x30, 0xE2, 0x02, 0x7F, 0x01, 0x90, 0x8F, 0x4B, 0xEF, 0xF0, 0x90, 0x8F, 0x2E, 0xE0, 0x54, 0xEF, -0xF0, 0xE4, 0x90, 0x91, 0x33, 0xF0, 0x90, 0x91, 0x3B, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, -0x90, 0x91, 0x3F, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x90, 0x91, 0x37, 0x12, 0x08, 0x79, -0x00, 0x00, 0x00, 0x00, 0x90, 0x93, 0x73, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x22, 0xEF, -0xF0, 0x90, 0xFD, 0x78, 0xE0, 0x7F, 0x00, 0x22, 0xEF, 0xF0, 0x90, 0xFD, 0x70, 0xE0, 0x7F, 0x00, -0x22, 0xEE, 0xF0, 0x90, 0xFD, 0x80, 0xE0, 0x7E, 0x00, 0x22, 0x90, 0x8F, 0x2E, 0xE0, 0xFF, 0xC4, -0x54, 0x0F, 0x30, 0xE0, 0x05, 0x12, 0x93, 0x31, 0x11, 0x7A, 0x22, 0x90, 0x93, 0xAB, 0xEC, 0xF0, -0xA3, 0xED, 0xF0, 0x90, 0x93, 0xA9, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x93, 0xCF, 0xF0, -0xEF, 0x24, 0x24, 0xFF, 0xE4, 0x3E, 0xFE, 0xC0, 0x06, 0x71, 0x65, 0xD0, 0x06, 0xE4, 0xFB, 0xFA, -0x71, 0x39, 0x4E, 0x60, 0x42, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x93, 0xD0, 0x12, 0x5F, 0x1A, 0x90, -0x93, 0xAE, 0x71, 0x45, 0x90, 0x93, 0xAE, 0x71, 0x50, 0xFE, 0xC3, 0x9F, 0x50, 0x29, 0x90, 0x93, -0xD1, 0xE0, 0x24, 0x02, 0xFD, 0x90, 0x93, 0xD0, 0xE0, 0x34, 0x00, 0xFC, 0xEE, 0x7E, 0x00, 0x2D, -0x12, 0x5C, 0xF8, 0x90, 0x93, 0xAD, 0xE0, 0x24, 0xAF, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, -0xEF, 0xF0, 0x12, 0x65, 0x73, 0x80, 0xCD, 0x71, 0x57, 0xFE, 0xC0, 0x06, 0x71, 0x65, 0xD0, 0x06, -0x7B, 0x03, 0x71, 0x36, 0x90, 0x93, 0xAA, 0xE0, 0x24, 0x22, 0x71, 0x5D, 0xFE, 0x90, 0x93, 0xD0, -0x12, 0x5F, 0xE0, 0xEF, 0x20, 0xE4, 0x02, 0x41, 0x1F, 0x90, 0x93, 0xCF, 0xE0, 0x04, 0xF0, 0x71, -0x57, 0xFE, 0xC0, 0x06, 0x71, 0x65, 0xD0, 0x06, 0x7B, 0x30, 0x71, 0x36, 0x4E, 0x60, 0x46, 0xE0, -0x24, 0x08, 0xFF, 0x90, 0x93, 0xD0, 0x12, 0x5F, 0x1A, 0x90, 0x93, 0xD3, 0x71, 0x45, 0x71, 0x4D, -0xC3, 0x9F, 0x50, 0x31, 0x90, 0x93, 0xD1, 0xE0, 0x24, 0x0D, 0xFF, 0x90, 0x93, 0xD0, 0x12, 0x5F, -0x1A, 0x90, 0x93, 0xD2, 0xEF, 0xF0, 0xBF, 0x02, 0x09, 0x90, 0x93, 0xCF, 0xE0, 0x24, 0x20, 0xF0, -0x80, 0x0E, 0x90, 0x93, 0xD2, 0xE0, 0xB4, 0x04, 0x07, 0x90, 0x93, 0xCF, 0xE0, 0x24, 0x40, 0xF0, -0x12, 0x65, 0x69, 0x80, 0xC9, 0x71, 0x57, 0xFE, 0xC0, 0x06, 0x71, 0x65, 0xD0, 0x06, 0x7B, 0xDD, -0x7A, 0x00, 0x7D, 0x01, 0x71, 0x3A, 0x4E, 0x60, 0x4B, 0xE0, 0x24, 0x0C, 0xFF, 0x90, 0x93, 0xD0, -0x12, 0x5F, 0x1A, 0x90, 0x93, 0xD3, 0x71, 0x45, 0x71, 0x4D, 0xC3, 0x9F, 0x50, 0x36, 0x90, 0x93, -0xD1, 0xE0, 0x24, 0x11, 0xFF, 0x90, 0x93, 0xD0, 0x12, 0x5F, 0x1A, 0x90, 0x93, 0xD2, 0xEF, 0xF0, -0xBF, 0x02, 0x09, 0x90, 0x93, 0xCF, 0xE0, 0x24, 0x02, 0xF0, 0x80, 0x0E, 0x90, 0x93, 0xD2, 0xE0, -0xB4, 0x04, 0x07, 0x90, 0x93, 0xCF, 0xE0, 0x24, 0x04, 0xF0, 0x12, 0x65, 0x69, 0x80, 0xC9, 0xE4, -0x90, 0x93, 0xCF, 0xF0, 0x90, 0x91, 0x33, 0xE0, 0x90, 0x04, 0xFD, 0x71, 0x46, 0x90, 0x91, 0x33, -0x71, 0x50, 0xFE, 0xC3, 0x9F, 0x50, 0x65, 0x12, 0x9F, 0x4A, 0xE0, 0xFF, 0x90, 0x93, 0xAE, 0xE0, -0xFE, 0x6F, 0x70, 0x53, 0x90, 0x04, 0xFC, 0xE0, 0x04, 0xF0, 0x90, 0x93, 0xAD, 0xE0, 0x24, 0x53, -0x12, 0x9F, 0xC8, 0xE0, 0xFF, 0x90, 0x93, 0xCF, 0xE0, 0xFD, 0x4F, 0x60, 0x04, 0xED, 0x5F, 0x60, -0x36, 0xEE, 0xFF, 0x7E, 0x00, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x93, 0xAD, 0xE0, 0x75, 0xF0, 0x20, -0xA4, 0x24, 0x73, 0xF9, 0x74, 0x91, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x78, 0xAF, 0x7C, 0x93, 0x7D, -0x01, 0xD0, 0x07, 0xD0, 0x06, 0x12, 0x45, 0xC7, 0xEF, 0x70, 0x0C, 0x90, 0x01, 0xC7, 0x74, 0x55, -0xF0, 0x7F, 0x01, 0x71, 0xCF, 0x11, 0xCA, 0x12, 0x65, 0x73, 0x80, 0x91, 0x22, 0x90, 0x93, 0xD4, -0x12, 0x97, 0xE4, 0xA3, 0xEA, 0xF0, 0xA3, 0xEB, 0xF0, 0xC3, 0x90, 0x93, 0xDA, 0xE0, 0x94, 0x01, -0x90, 0x93, 0xD9, 0xE0, 0x94, 0x00, 0x50, 0x02, 0x80, 0x78, 0xE4, 0x90, 0x93, 0xDD, 0xF0, 0xA3, -0xF0, 0x71, 0x7A, 0xFF, 0xE4, 0xFD, 0x12, 0x5C, 0xFE, 0x90, 0x93, 0xD7, 0xE0, 0x70, 0x03, 0xA3, -0xE0, 0x6F, 0x70, 0x1B, 0x90, 0x93, 0xD5, 0xE0, 0x24, 0x02, 0x12, 0x98, 0x1C, 0xFE, 0x90, 0x93, -0xD6, 0xE0, 0xFD, 0x12, 0x9D, 0x8A, 0xBF, 0x01, 0x04, 0x71, 0x7A, 0xFF, 0x22, 0x80, 0x00, 0x90, -0x93, 0xD5, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x93, 0xD4, 0x12, 0x5F, 0x1A, 0x7E, 0x00, 0x90, 0x93, -0xDB, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x24, 0x02, 0xFF, 0xEE, 0x33, 0xFE, 0x90, 0x93, 0xD4, 0x8F, -0xF0, 0x12, 0x08, 0xD6, 0x90, 0x93, 0xDD, 0xEE, 0x8F, 0xF0, 0x12, 0x08, 0xD6, 0x90, 0x93, 0xD9, -0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x93, 0xDE, 0xE0, 0x9F, 0x90, 0x93, 0xDD, 0xE0, 0x9E, -0x40, 0x8F, 0xE4, 0xFE, 0xFF, 0x22, 0x7A, 0x00, 0xE4, 0xFD, 0x51, 0x9D, 0x90, 0x93, 0xD0, 0xEE, -0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xEF, 0xF0, 0xE4, 0x90, 0x93, 0xAD, 0xF0, 0x22, 0x90, 0x93, 0xD3, -0xE0, 0xFF, 0x90, 0x93, 0xAD, 0xE0, 0x22, 0x90, 0x93, 0xAA, 0xE0, 0x24, 0x24, 0xFF, 0x90, 0x93, -0xA9, 0xE0, 0x34, 0x00, 0x22, 0x90, 0x93, 0xAC, 0xE0, 0x24, 0xDC, 0xFE, 0x90, 0x93, 0xAB, 0xE0, -0x34, 0xFF, 0x90, 0x93, 0xD9, 0xF0, 0xA3, 0xCE, 0xF0, 0x22, 0x90, 0x93, 0xD4, 0xE0, 0xFE, 0xA3, -0xE0, 0x22, 0x71, 0x86, 0x01, 0xCA, 0x90, 0x8F, 0x2E, 0x12, 0x9F, 0xD0, 0x30, 0xE0, 0x02, 0x71, -0x92, 0x22, 0x91, 0x11, 0xE4, 0x90, 0x93, 0x83, 0x12, 0x4F, 0x9F, 0x90, 0x90, 0xDD, 0x12, 0x4F, -0x9F, 0xA3, 0x12, 0x4F, 0x9F, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x90, 0xEF, 0xF0, 0xA3, 0xF0, 0x90, -0x91, 0x31, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x9E, 0x6E, 0x90, 0x94, 0xB2, 0xE0, 0x64, 0x01, 0xF0, -0xE0, 0x24, 0xB6, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x73, 0xA3, 0x12, 0x5D, 0xA9, 0x01, 0xDB, 0x90, -0x95, 0x8D, 0xEF, 0xF0, 0x90, 0x8D, 0x06, 0xE0, 0x64, 0x02, 0x70, 0x22, 0x90, 0x95, 0x8D, 0xE0, -0xFD, 0x64, 0x01, 0x70, 0x28, 0x12, 0x5F, 0xD8, 0x90, 0x8F, 0x32, 0xE0, 0x91, 0x1B, 0x30, 0xE0, -0x09, 0x90, 0x01, 0x4D, 0xE0, 0x64, 0x80, 0xF0, 0x80, 0x13, 0xAF, 0x05, 0x80, 0x0C, 0x90, 0x06, -0x90, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x95, 0x8D, 0xE0, 0xFF, 0x12, 0x4C, 0x94, 0x12, 0x9A, 0x19, -0xF0, 0x90, 0x8F, 0x2E, 0xE0, 0x54, 0xBF, 0xF0, 0x22, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x13, 0x54, -0x01, 0x22, 0xF1, 0xCB, 0x12, 0x06, 0x89, 0xFF, 0x54, 0x7F, 0x90, 0x8E, 0x84, 0xF0, 0xEF, 0x91, -0x1B, 0xA3, 0xB1, 0xC9, 0xFF, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFE, 0x90, 0x8E, 0x82, 0xE0, 0x54, -0xF0, 0x4E, 0xF1, 0x82, 0x54, 0x01, 0x25, 0xE0, 0xFE, 0x90, 0x8E, 0x80, 0xE0, 0x54, 0xFD, 0x4E, -0xF0, 0xEF, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x12, 0x7F, 0x0A, 0x4F, 0xF1, 0x7A, 0x90, 0x8E, -0x83, 0xF0, 0x91, 0xF8, 0x30, 0xE0, 0x4D, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0xC3, 0x94, 0x04, 0x90, -0x8E, 0x96, 0x50, 0x04, 0xEF, 0xF0, 0x80, 0x25, 0x74, 0x03, 0xF0, 0x91, 0xF2, 0xE9, 0x24, 0x06, -0xF1, 0xD8, 0xFF, 0x74, 0x03, 0x24, 0xFD, 0xFE, 0xEF, 0xC4, 0x54, 0x0F, 0xFD, 0xEF, 0x54, 0x0F, -0xFF, 0xED, 0x2E, 0x54, 0x0F, 0xFE, 0xC4, 0x54, 0xF0, 0x4F, 0x12, 0x06, 0xCF, 0x91, 0xF2, 0x91, -0xF8, 0xC4, 0x54, 0x0F, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x8E, 0x8C, 0x50, 0x05, 0x74, 0x04, 0xF0, -0x80, 0x02, 0xEF, 0xF0, 0x91, 0xF2, 0xF1, 0xC5, 0xFD, 0x7F, 0x02, 0x12, 0x53, 0xDC, 0x90, 0x94, -0xD0, 0xE0, 0x60, 0x03, 0x12, 0x53, 0xD0, 0x91, 0xF2, 0x90, 0x93, 0xAE, 0x12, 0x44, 0x12, 0x12, -0x9A, 0x20, 0x90, 0x8E, 0x84, 0xE0, 0xFF, 0x12, 0x6C, 0x2D, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x11, -0x90, 0x93, 0xAE, 0x12, 0x44, 0x09, 0xB1, 0xCA, 0x54, 0x0F, 0xFF, 0xF1, 0x7B, 0xFD, 0x12, 0x9A, -0xAB, 0x22, 0x90, 0x93, 0xAB, 0x02, 0x44, 0x09, 0x90, 0x00, 0x06, 0x02, 0x06, 0xA2, 0x90, 0x95, -0x1C, 0x12, 0x44, 0x12, 0x12, 0x06, 0x89, 0x90, 0x95, 0x21, 0xB1, 0xC9, 0x90, 0x95, 0x22, 0xF1, -0xC4, 0x90, 0x95, 0x23, 0xF1, 0xD1, 0x90, 0x95, 0x24, 0xF0, 0x91, 0xF8, 0x90, 0x95, 0x25, 0xF0, -0x90, 0x00, 0x07, 0x12, 0x06, 0xA2, 0x90, 0x95, 0x26, 0xF1, 0x82, 0x90, 0x95, 0x29, 0xF0, 0xED, -0x70, 0x19, 0xFF, 0xD1, 0xA8, 0xE0, 0xB4, 0xFF, 0x06, 0xD1, 0xA8, 0xE4, 0xF0, 0x80, 0x07, 0xD1, -0xA8, 0xE0, 0x04, 0xF0, 0x80, 0x05, 0x0F, 0xEF, 0xB4, 0x06, 0xE8, 0x90, 0x95, 0x20, 0xE0, 0xFF, -0xB4, 0x04, 0x14, 0xA3, 0xE0, 0xFE, 0xB1, 0xC2, 0xEE, 0xF1, 0xE7, 0xFE, 0xB1, 0xC2, 0x12, 0x90, -0x4B, 0x90, 0x00, 0x02, 0xE4, 0x80, 0x20, 0xEF, 0xB4, 0x02, 0x1F, 0x90, 0x95, 0x22, 0xB1, 0xC0, -0xEF, 0xF1, 0xE7, 0x44, 0x20, 0x54, 0x7F, 0xB1, 0xC1, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x06, 0xE1, -0x90, 0x95, 0x21, 0xE0, 0x90, 0x00, 0x02, 0x12, 0x06, 0xE1, 0xB1, 0xC2, 0xE9, 0x24, 0x03, 0xF1, -0xD8, 0x44, 0x20, 0x12, 0x06, 0xCF, 0x90, 0x95, 0x23, 0xB1, 0xC0, 0x90, 0x00, 0x04, 0xEF, 0x12, -0x06, 0xE1, 0x90, 0x95, 0x24, 0xE0, 0x90, 0x00, 0x05, 0x12, 0x06, 0xE1, 0x90, 0x95, 0x25, 0xE0, -0x90, 0x00, 0x06, 0x12, 0x06, 0xE1, 0x90, 0x95, 0x26, 0xE0, 0x90, 0x00, 0x07, 0x02, 0x06, 0xE1, -0xE0, 0xFF, 0x90, 0x95, 0x1C, 0x02, 0x44, 0x09, 0x4E, 0xF0, 0x90, 0x00, 0x01, 0x02, 0x06, 0xA2, -0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0xCB, 0x12, 0x06, 0x89, 0x20, 0xE0, 0x05, 0x12, -0x91, 0x02, 0xC1, 0xA3, 0x90, 0x90, 0x01, 0x74, 0x05, 0xF0, 0x12, 0x86, 0x25, 0x90, 0x8F, 0x31, -0x12, 0x87, 0xE5, 0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0xFF, 0x90, 0x8F, 0x31, 0x12, 0x9E, 0xAA, 0x54, -0x10, 0xFD, 0xEF, 0x54, 0xEF, 0xF1, 0xDF, 0x54, 0x20, 0xFE, 0xEF, 0x54, 0xDF, 0x12, 0x9E, 0xB2, -0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0xF1, 0xDF, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F, 0xB1, 0xC8, -0x54, 0x80, 0xFF, 0x90, 0x8F, 0x32, 0xE0, 0x54, 0x7F, 0x4F, 0xF0, 0x12, 0x06, 0x89, 0x13, 0x13, -0x54, 0x3F, 0x30, 0xE0, 0x07, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x04, 0xF0, 0x91, 0xF2, 0x12, 0x06, -0x89, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x08, 0xF0, -0x90, 0x8D, 0x06, 0xE0, 0xB4, 0x02, 0x09, 0x90, 0x8F, 0x32, 0xE0, 0x91, 0x1B, 0x20, 0xE0, 0x35, -0xB1, 0xCA, 0x54, 0x7F, 0xFF, 0x90, 0x8F, 0x32, 0xE0, 0x54, 0x80, 0x4F, 0xF1, 0x7A, 0x90, 0x8F, -0x33, 0xF1, 0x82, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x8F, 0x34, 0x12, 0x86, 0x1D, 0x54, 0xFE, 0xFF, -0xEE, 0x54, 0x01, 0x4F, 0xF0, 0x12, 0x4D, 0x34, 0x13, 0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, -0x7D, 0x01, 0x12, 0x4A, 0xA6, 0x90, 0x8D, 0x06, 0xE0, 0xB4, 0x01, 0x07, 0x90, 0xFE, 0x10, 0xE0, -0x44, 0x04, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x95, -0xF5, 0x83, 0x22, 0x12, 0x06, 0x89, 0x90, 0x06, 0x74, 0xB1, 0xC9, 0x90, 0x06, 0x75, 0xF1, 0x7A, -0x90, 0x06, 0x76, 0xF1, 0x82, 0x90, 0x06, 0x77, 0xF0, 0x90, 0x06, 0x70, 0xEF, 0xF0, 0xA3, 0xE4, -0xF0, 0xA3, 0x04, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x7F, 0x01, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x90, -0x94, 0x09, 0x12, 0x9F, 0xA0, 0x90, 0x94, 0x0A, 0x12, 0x56, 0xE5, 0xF1, 0x54, 0x24, 0x02, 0xF1, -0x69, 0x24, 0x04, 0xF1, 0x4B, 0x24, 0x03, 0xF1, 0x69, 0x24, 0x08, 0xF1, 0x4B, 0x24, 0x04, 0xF1, -0x69, 0x24, 0x0C, 0xF1, 0x4B, 0x24, 0x05, 0xFF, 0x7B, 0x01, 0x7A, 0x94, 0x79, 0x0D, 0xD1, 0xB3, -0x90, 0x94, 0x09, 0xE0, 0xFE, 0x44, 0x10, 0x90, 0x94, 0x0D, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0xA3, -0x74, 0xFF, 0xF0, 0xA3, 0xF0, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0xFF, 0x7B, 0x01, 0x7A, 0x94, 0x79, -0x0D, 0xD1, 0xB3, 0x90, 0x94, 0x0D, 0x12, 0x4F, 0x9D, 0xF1, 0x60, 0x04, 0xFF, 0x7B, 0x01, 0x7A, -0x94, 0x79, 0x0D, 0xD1, 0xB3, 0x90, 0x06, 0x72, 0xE4, 0xF0, 0x22, 0xF9, 0xE4, 0x3A, 0x8B, 0x40, -0xF5, 0x41, 0x89, 0x42, 0x75, 0x43, 0x04, 0x7B, 0x01, 0x7A, 0x94, 0x79, 0x0D, 0x12, 0x35, 0x26, -0x90, 0x94, 0x09, 0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x22, 0xFF, 0x7B, 0x01, 0x7A, 0x94, 0x79, 0x0D, -0xD1, 0xB3, 0x90, 0x94, 0x0A, 0x12, 0x44, 0x09, 0xE9, 0x22, 0xF0, 0x90, 0x00, 0x02, 0x02, 0x06, -0xA2, 0x4F, 0xF0, 0x90, 0x00, 0x03, 0x02, 0x06, 0xA2, 0x90, 0x02, 0x09, 0xE0, 0xF5, 0x51, 0x12, -0x06, 0x89, 0x25, 0x51, 0x90, 0x8D, 0x07, 0xB1, 0xC9, 0x25, 0x51, 0x90, 0x8D, 0x08, 0xF1, 0x7A, -0x25, 0x51, 0x90, 0x8D, 0x09, 0xF1, 0x82, 0x25, 0x51, 0x90, 0x8D, 0x0A, 0xF1, 0xC4, 0x25, 0x51, -0x90, 0x8D, 0x0B, 0xF1, 0xD1, 0x25, 0x51, 0x90, 0x8D, 0x0C, 0xF0, 0x91, 0xF8, 0x25, 0x51, 0x90, -0x8D, 0x0D, 0xF0, 0x22, 0xF0, 0x90, 0x00, 0x04, 0x02, 0x06, 0xA2, 0x90, 0x93, 0xAB, 0x02, 0x44, -0x12, 0xF0, 0x90, 0x00, 0x05, 0x02, 0x06, 0xA2, 0xF9, 0xE4, 0x3A, 0xFA, 0x02, 0x06, 0x89, 0x4D, -0xFF, 0x90, 0x8F, 0x31, 0xF0, 0xEE, 0x22, 0x12, 0x06, 0xCF, 0x90, 0x95, 0x22, 0xE0, 0x22, 0xC0, +0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0x41, 0x95, 0x1A, 0x00, 0x41, 0x95, 0x1B, 0x00, 0x41, +0x95, 0x2C, 0x00, 0x41, 0x94, 0x6F, 0x00, 0x41, 0x94, 0x51, 0x00, 0x44, 0x95, 0x0D, 0x00, 0x50, +0xF2, 0x01, 0x00, 0x4B, 0xAE, 0x60, 0x04, 0x67, 0xFC, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x8F, 0x82, 0x75, 0x83, 0x00, 0xED, 0xF1, 0xDF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, 0xF5, 0xEF, 0xF0, 0x90, 0x94, 0xF7, 0xEB, 0xF0, 0xED, 0x60, +0x02, 0x21, 0xF7, 0x90, 0x07, 0x6E, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x07, 0x65, 0xE0, 0x54, 0xE7, +0xF0, 0x90, 0x94, 0xF7, 0xE0, 0x70, 0x3B, 0xB1, 0x58, 0xD1, 0x21, 0x70, 0x2F, 0x12, 0xA1, 0x20, +0x70, 0x13, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0x74, 0x02, 0xFE, 0x91, 0xFE, 0x7F, 0x64, 0x51, 0x4E, +0xEF, 0x54, 0xFE, 0x80, 0x12, 0x12, 0x37, 0x4E, 0xE4, 0xFE, 0x74, 0x80, 0xFF, 0xE4, 0x91, 0xFE, +0x7F, 0x64, 0x51, 0x4E, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x64, 0x31, 0x39, 0x7F, 0x4E, 0xD1, 0x81, +0x41, 0x40, 0xB1, 0x58, 0xD1, 0x21, 0x70, 0x06, 0xD1, 0x2F, 0xFF, 0xFE, 0x91, 0xFE, 0xD1, 0x38, +0xB1, 0x63, 0x44, 0x01, 0xFD, 0x7F, 0x4F, 0x31, 0x39, 0x7F, 0x30, 0xD1, 0x31, 0x74, 0x66, 0xFF, +0xEC, 0x12, 0x61, 0x5B, 0x7F, 0x30, 0x7E, 0x09, 0x12, 0x38, 0x45, 0x7F, 0x2C, 0x7E, 0x09, 0x12, +0x37, 0x4E, 0xEF, 0x54, 0xFC, 0xFF, 0xEF, 0x44, 0x01, 0xFF, 0xEC, 0x12, 0x61, 0x5B, 0x7F, 0x2C, +0x7E, 0x09, 0x12, 0x38, 0x45, 0x80, 0x52, 0x90, 0x07, 0x6E, 0xE0, 0x54, 0xF7, 0xF0, 0x90, 0x07, +0x65, 0xE0, 0x44, 0x18, 0xF0, 0x90, 0x94, 0xF5, 0xE0, 0x70, 0x33, 0x90, 0x94, 0xF7, 0xE0, 0x60, +0x09, 0xB1, 0x58, 0x31, 0x39, 0xD1, 0x2F, 0xFF, 0x80, 0x21, 0x7F, 0x67, 0x51, 0x4E, 0xEF, 0x54, +0xDF, 0xFD, 0x7F, 0x67, 0x31, 0x39, 0x12, 0xA1, 0x20, 0x70, 0x0B, 0x12, 0x37, 0x4E, 0xE4, 0x74, +0x80, 0xFF, 0x74, 0x02, 0x80, 0x05, 0x12, 0x37, 0x4E, 0xE4, 0xFF, 0xFE, 0x91, 0xFE, 0xD1, 0x38, +0xB1, 0x63, 0x54, 0xFE, 0xFD, 0x7F, 0x4F, 0x31, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x82, 0x75, 0x83, 0x00, 0xE0, 0x90, 0x95, 0x26, 0xF1, 0xDF, +0x90, 0x95, 0x26, 0xE0, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x95, 0x21, 0xED, 0xF0, 0x90, 0x95, 0x20, 0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x41, +0x7F, 0x47, 0x71, 0x0F, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0xFD, 0x7F, 0x47, 0x31, +0x39, 0x7F, 0x46, 0x71, 0x0F, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0xFD, 0x7F, 0x46, 0xD1, +0x28, 0x60, 0x0D, 0x7F, 0x45, 0x71, 0x0F, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4F, 0x80, 0x0C, +0x7F, 0x45, 0x71, 0x0F, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0xFD, 0x7F, 0x45, 0x80, +0x45, 0x90, 0x95, 0x20, 0xE0, 0x24, 0xF8, 0xF0, 0x7F, 0x63, 0x71, 0x0F, 0x80, 0x02, 0xC3, 0x33, +0xD8, 0xFC, 0xF4, 0x5F, 0xFD, 0x7F, 0x63, 0x31, 0x39, 0x7F, 0x62, 0x71, 0x0F, 0x80, 0x02, 0xC3, +0x33, 0xD8, 0xFC, 0x4F, 0xFD, 0x7F, 0x62, 0xD1, 0x28, 0x60, 0x0E, 0x71, 0x0D, 0x80, 0x02, 0xC3, +0x33, 0xD8, 0xFC, 0x4F, 0xFD, 0x7F, 0x61, 0x80, 0x0D, 0x71, 0x0D, 0x80, 0x02, 0xC3, 0x33, 0xD8, +0xFC, 0xF4, 0x5F, 0xFD, 0x7F, 0x61, 0x31, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x61, 0x51, +0x4E, 0x90, 0x95, 0x20, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x22, 0x7F, 0xFF, 0x12, 0x53, +0xD9, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0xFA, 0x7D, 0x01, 0x31, 0x4D, 0x12, 0x8F, +0xD0, 0x71, 0x68, 0x71, 0x55, 0x71, 0x55, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x31, 0x39, 0x90, 0x01, +0x00, 0x74, 0x3F, 0xF0, 0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x20, 0xF0, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x31, 0x39, 0x7F, 0x02, 0x51, 0x4E, +0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x02, 0x31, 0x39, 0x7F, 0x02, 0x51, 0x4E, 0xEF, 0x22, 0x7F, 0x54, +0x51, 0x4E, 0xE5, 0x0D, 0x5F, 0xF5, 0x11, 0x7F, 0x55, 0x51, 0x4E, 0xE5, 0x0E, 0x5F, 0xF5, 0x12, +0x7F, 0x56, 0x51, 0x4E, 0xE5, 0x0F, 0x5F, 0xF5, 0x13, 0x7F, 0x57, 0x51, 0x4E, 0xE5, 0x10, 0x5F, +0xF5, 0x14, 0xAD, 0x11, 0x7F, 0x54, 0x31, 0x39, 0xAD, 0x12, 0x7F, 0x55, 0x31, 0x39, 0xAD, 0x13, +0x7F, 0x56, 0x31, 0x39, 0xAD, 0x14, 0x7F, 0x57, 0x31, 0x39, 0x53, 0x91, 0xEF, 0x22, 0x7F, 0x81, +0x51, 0x4E, 0xEF, 0x54, 0xFE, 0xFD, 0x7F, 0x81, 0x31, 0x39, 0x7F, 0x80, 0xD1, 0x81, 0xFD, 0x7F, +0x80, 0x31, 0x39, 0x12, 0x8B, 0xA5, 0x12, 0x3E, 0x11, 0xF1, 0xF7, 0x12, 0x8C, 0x07, 0x7F, 0x01, +0x12, 0x47, 0x00, 0x90, 0x93, 0x27, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x47, 0x00, 0x90, 0x93, 0x27, +0xE0, 0x04, 0xF0, 0x91, 0x13, 0x12, 0x88, 0xCC, 0x7F, 0x80, 0xF1, 0xBA, 0x7F, 0x80, 0x31, 0x39, +0x75, 0x28, 0xFF, 0x12, 0x5F, 0xFD, 0x12, 0x8B, 0xCC, 0x12, 0x90, 0x33, 0x7F, 0x81, 0x51, 0x4E, +0xEF, 0x44, 0x04, 0xFD, 0x7F, 0x81, 0x31, 0x39, 0x12, 0x8C, 0x11, 0x12, 0x90, 0x5E, 0xE4, 0xFF, +0x02, 0x47, 0x89, 0xF1, 0xC1, 0x90, 0x8D, 0x06, 0xEF, 0xF0, 0xD1, 0x40, 0x90, 0x01, 0x64, 0x74, +0x01, 0xF0, 0x90, 0x04, 0x23, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x17, 0x51, 0x4E, 0xEF, 0x54, 0xFC, +0x44, 0x04, 0xFD, 0x7F, 0x17, 0x31, 0x39, 0x7F, 0x16, 0x51, 0x4E, 0xEF, 0x54, 0x0F, 0x44, 0x40, +0xFD, 0x7F, 0x16, 0x31, 0x39, 0x7F, 0x38, 0xF1, 0xBA, 0x7F, 0x38, 0x31, 0x39, 0x02, 0x37, 0x99, +0xAD, 0x07, 0x90, 0x8E, 0xC9, 0xE0, 0x75, 0xF0, 0x40, 0xA4, 0xFF, 0x90, 0x95, 0x09, 0xE5, 0xF0, +0x12, 0xA1, 0x31, 0x90, 0x8E, 0xCA, 0xE0, 0xC3, 0x13, 0x54, 0x7F, 0x90, 0x95, 0x0C, 0xF0, 0xED, +0x64, 0x01, 0x70, 0x70, 0x90, 0x95, 0x09, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x60, 0x0B, 0x90, 0x95, +0x09, 0x74, 0xFF, 0x75, 0xF0, 0xD0, 0x12, 0x08, 0xD6, 0x91, 0xF0, 0x13, 0x54, 0x07, 0x7D, 0x00, +0x20, 0xE0, 0x02, 0x7D, 0x01, 0x51, 0x6A, 0x91, 0xF0, 0x13, 0x54, 0x01, 0xFD, 0x51, 0x6A, 0x90, +0x8E, 0xCA, 0xE0, 0x30, 0xE0, 0x3E, 0x91, 0xE5, 0x13, 0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, +0x7D, 0x01, 0x51, 0x6A, 0xE4, 0x90, 0x95, 0x0B, 0xF0, 0x90, 0x95, 0x0C, 0xE0, 0xFF, 0x90, 0x95, +0x0B, 0xE0, 0xC3, 0x9F, 0x50, 0x1E, 0x91, 0xE5, 0x13, 0x54, 0x01, 0xFD, 0x51, 0x6A, 0x91, 0xE5, +0x13, 0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x51, 0x6A, 0x90, 0x95, 0x0B, 0xE0, +0x04, 0xF0, 0x80, 0xD5, 0x22, 0x90, 0x95, 0x09, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x3E, 0x50, +0x90, 0x8E, 0xC8, 0xE0, 0x54, 0x7F, 0xFF, 0x90, 0x8E, 0xC7, 0xE0, 0xFE, 0xC4, 0x22, 0xEC, 0x90, +0xAA, 0xB9, 0x12, 0x08, 0x6D, 0x7F, 0x48, 0x7E, 0x09, 0x02, 0x38, 0x45, 0x90, 0x8E, 0x12, 0xE0, +0x44, 0x10, 0xF0, 0x90, 0x8E, 0x20, 0xE0, 0xFD, 0x7F, 0x93, 0x31, 0x39, 0x90, 0x8E, 0x16, 0xE0, +0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, 0x10, 0xF0, 0x80, 0x06, 0x90, 0x01, +0x2F, 0x74, 0x90, 0xF0, 0x7F, 0x08, 0x51, 0x4E, 0xEF, 0x44, 0x10, 0xFD, 0x7F, 0x08, 0x31, 0x39, +0x7F, 0x01, 0x12, 0x60, 0xA4, 0x7F, 0x90, 0x51, 0x4E, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x90, 0x31, +0x39, 0x7F, 0x14, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x7F, 0x67, 0x51, 0x4E, 0xEF, 0x44, 0x20, 0xFD, +0x7F, 0x67, 0x22, 0xFD, 0x7F, 0x4E, 0x31, 0x39, 0x7F, 0x4F, 0x51, 0x4E, 0xEF, 0x22, 0x90, 0x01, +0x30, 0xE4, 0xB1, 0xB3, 0x90, 0x01, 0x38, 0xB1, 0xB3, 0xFD, 0x7F, 0x50, 0x31, 0x39, 0xE4, 0xFD, +0x7F, 0x51, 0x31, 0x39, 0xE4, 0xFD, 0x7F, 0x52, 0x31, 0x39, 0xE4, 0xFD, 0x7F, 0x53, 0x21, 0x39, +0x90, 0x01, 0x34, 0x74, 0xFF, 0xB1, 0xB3, 0x90, 0x01, 0x3C, 0xB1, 0xB3, 0xFD, 0x7F, 0x54, 0x31, +0x39, 0x7D, 0xFF, 0x7F, 0x55, 0x31, 0x39, 0x7D, 0xFF, 0x7F, 0x56, 0x31, 0x39, 0x7D, 0xFF, 0x7F, +0x57, 0x21, 0x39, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0xD1, 0x1B, 0x30, 0xE6, 0x1B, 0x90, 0x00, 0x8C, 0xE0, 0xF5, 0x26, 0x7F, 0x8D, 0x51, +0x4E, 0x90, 0x00, 0x8E, 0xE0, 0xF5, 0x27, 0xD1, 0x1B, 0x30, 0xE0, 0x06, 0xE4, 0xFD, 0x7F, 0x8D, +0x31, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, +0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, +0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0, 0xF1, 0xFA, 0xE4, 0xFD, 0x31, 0x4D, 0x71, 0x68, 0x44, +0x01, 0xFD, 0x7F, 0x02, 0x31, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x8F, 0x51, 0x4E, 0xEF, +0x22, 0x31, 0x39, 0x90, 0x94, 0xF5, 0xE0, 0x22, 0x31, 0x39, 0x90, 0x95, 0x21, 0xE0, 0x22, 0x7F, +0x48, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0xE4, 0x22, 0x7F, 0x4E, 0x51, 0x4E, 0xEF, 0x54, 0x7F, 0x22, +0xB1, 0x6E, 0xB1, 0x90, 0x12, 0x8B, 0x67, 0x12, 0x8B, 0x86, 0xE4, 0xF5, 0x0D, 0xF5, 0x0E, 0xF5, +0x0F, 0x75, 0x10, 0x80, 0xAD, 0x0D, 0x7F, 0x50, 0x31, 0x39, 0xAD, 0x0E, 0x7F, 0x51, 0x31, 0x39, +0xAD, 0x0F, 0x7F, 0x52, 0x31, 0x39, 0xAD, 0x10, 0x7F, 0x53, 0x21, 0x39, 0x12, 0xA1, 0x39, 0x7F, +0xF2, 0x51, 0x4E, 0xEF, 0x20, 0xE6, 0x09, 0x7F, 0x05, 0xD1, 0x81, 0xFD, 0x7F, 0x05, 0x31, 0x39, +0x22, 0x51, 0x4E, 0xEF, 0x44, 0x80, 0x22, 0x12, 0x79, 0x62, 0xE4, 0x90, 0x93, 0x22, 0xB1, 0xB3, +0x90, 0x90, 0x74, 0xB1, 0xB3, 0xA3, 0xB1, 0xB3, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x90, 0x86, 0xF0, +0xA3, 0xF0, 0x90, 0x90, 0xC8, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x8E, 0x17, 0xE0, 0x90, 0x94, 0x6B, +0xF0, 0x7D, 0x02, 0x7F, 0x02, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x2D, 0xEF, +0xF0, 0x14, 0x60, 0x15, 0x14, 0x60, 0x19, 0x24, 0x02, 0x70, 0x1A, 0xED, 0x54, 0x01, 0xFF, 0x90, +0x8E, 0x11, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x80, 0x0C, 0x90, 0x8E, 0x18, 0xED, 0xF0, 0x80, 0x05, +0x90, 0x8E, 0x17, 0xED, 0xF0, 0xD1, 0x1B, 0x30, 0xE4, 0x30, 0x90, 0x95, 0x2D, 0xE0, 0x14, 0x60, +0x07, 0x14, 0x60, 0x1D, 0x24, 0x02, 0x70, 0x22, 0x90, 0x8E, 0x11, 0xE0, 0x54, 0x01, 0xC4, 0x33, +0x33, 0x33, 0x54, 0x80, 0xFF, 0x90, 0x8E, 0x18, 0xE0, 0x54, 0x7F, 0x4F, 0xFD, 0x7F, 0x88, 0x80, +0x07, 0x90, 0x8E, 0x17, 0xE0, 0xFD, 0x7F, 0x89, 0x31, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7E, +0x00, 0x7F, 0xA8, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x8E, 0x79, 0x11, 0x12, 0x08, 0xAA, 0x12, 0x89, +0xB2, 0x12, 0x08, 0xAA, 0x90, 0x8E, 0x14, 0x74, 0x02, 0xF0, 0x90, 0x8E, 0x1B, 0x14, 0x12, 0xA1, +0x80, 0x90, 0x8E, 0x21, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x12, 0xA0, 0x26, 0xE4, 0xFD, 0xFF, +0xD1, 0xB5, 0x7D, 0x0C, 0x7F, 0x02, 0xD1, 0xB5, 0xF1, 0xD9, 0x90, 0x8D, 0x06, 0xE0, 0xFF, 0xB4, +0x01, 0x08, 0x90, 0x8E, 0x20, 0x74, 0xDD, 0xF0, 0x80, 0x0F, 0xEF, 0x90, 0x8E, 0x20, 0xB4, 0x03, +0x05, 0x74, 0xD4, 0xF0, 0x80, 0x03, 0x74, 0x40, 0xF0, 0x7F, 0x79, 0x51, 0x4E, 0xEF, 0x54, 0x03, +0xFF, 0xBF, 0x02, 0x0E, 0x7F, 0x28, 0x51, 0x4E, 0xEF, 0x30, 0xE2, 0x06, 0x90, 0x8E, 0x4B, 0x74, +0x02, 0xF0, 0x12, 0x7F, 0x83, 0x12, 0xA0, 0x26, 0x7F, 0x01, 0x12, 0x9D, 0x05, 0x7E, 0x00, 0x7F, +0x02, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x8E, 0x79, 0xBD, 0x12, 0x08, 0xAA, 0x12, 0x67, 0xF4, 0x12, +0xA1, 0x29, 0xF1, 0xE9, 0xE4, 0x90, 0x8E, 0xBF, 0xF0, 0x22, 0x51, 0x4E, 0xEF, 0x44, 0x40, 0xFD, +0x22, 0x7F, 0xF4, 0x51, 0x4E, 0xEF, 0x20, 0xE5, 0x0D, 0x7F, 0xF4, 0x51, 0x4E, 0xEF, 0x7F, 0x01, +0x20, 0xE4, 0x05, 0x7F, 0x02, 0x22, 0x7F, 0x03, 0x22, 0x7D, 0x0C, 0x7F, 0x01, 0xC1, 0xB5, 0xF0, +0x7F, 0x10, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0xB1, 0xE7, 0xE4, 0xFD, 0xFF, 0x02, 0x53, 0xD9, 0xF1, +0xE7, 0x7D, 0x0C, 0x7F, 0x01, 0xC1, 0xB5, 0x22, 0xA1, 0xBB, 0x90, 0x8E, 0xE2, 0xE0, 0xFF, 0x90, +0x8E, 0xE1, 0xE0, 0xFB, 0x90, 0x8E, 0xE3, 0xE0, 0x90, 0x94, 0xF8, 0xF0, 0x22, 0x90, 0x94, 0xE3, +0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x94, 0xDE, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x94, 0xE2, 0xE0, 0xF5, 0x3B, 0xA3, 0xE0, 0xF5, +0x3C, 0x12, 0x36, 0x3E, 0x90, 0x94, 0xDE, 0x12, 0xA1, 0x17, 0xA3, 0xA3, 0xA3, 0x74, 0x05, 0xF0, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x90, 0x94, 0xE9, 0xF0, 0x7F, 0x03, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x94, 0xE4, 0xEF, 0xF0, 0x12, 0x90, 0x4C, 0x90, 0x94, 0xE4, 0xE0, 0xFF, +0x31, 0x5B, 0x74, 0x01, 0xF0, 0x90, 0x94, 0xE9, 0xE0, 0xFE, 0xEF, 0x31, 0x69, 0xEE, 0xF0, 0x90, +0x94, 0xE4, 0xE0, 0x11, 0xB0, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x11, 0xA5, 0x78, 0x10, +0x12, 0x08, 0x47, 0xAB, 0x07, 0x11, 0xA5, 0x78, 0x08, 0x12, 0x08, 0x47, 0x90, 0x94, 0xE2, 0xEF, +0xF0, 0x11, 0xA5, 0x90, 0x94, 0xE3, 0xEF, 0xF0, 0x7D, 0x01, 0x7F, 0x50, 0x7E, 0x01, 0x11, 0x18, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x94, 0xE5, 0x02, 0x43, 0xE5, 0x90, 0x93, 0x46, 0xE0, 0xFB, +0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0xE4, 0x90, +0x93, 0x46, 0xF0, 0x90, 0x93, 0x46, 0xE0, 0xFF, 0xC3, 0x94, 0x08, 0x40, 0x02, 0x21, 0x53, 0xEF, +0x31, 0x5B, 0xE0, 0x64, 0x01, 0x70, 0x74, 0x90, 0x93, 0x46, 0xE0, 0x11, 0xB0, 0x12, 0x43, 0xE5, +0xE4, 0x7B, 0x01, 0x31, 0x54, 0x70, 0x3A, 0x90, 0x93, 0x46, 0xE0, 0xFB, 0x31, 0x69, 0xE0, 0x60, +0x21, 0x14, 0x70, 0x57, 0xEB, 0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x05, 0xF5, 0x82, 0xE4, 0x34, 0x94, +0xF5, 0x83, 0x12, 0x43, 0xE5, 0xEB, 0x11, 0xB0, 0x12, 0x08, 0x6D, 0x90, 0x93, 0x46, 0xE0, 0xFF, +0x80, 0x0B, 0x11, 0xAB, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x03, 0x31, 0x77, 0x80, +0x2A, 0x90, 0x93, 0x46, 0xE0, 0x11, 0xB0, 0x12, 0x43, 0xE5, 0xE4, 0xFB, 0x31, 0x54, 0x50, 0x1B, +0x11, 0xAB, 0x12, 0x43, 0xE5, 0xEF, 0x24, 0xFF, 0xFF, 0xEE, 0x34, 0xFF, 0xFE, 0xED, 0x34, 0xFF, +0xFD, 0xEC, 0x34, 0xFF, 0xFC, 0xEB, 0x11, 0xB0, 0x12, 0x08, 0x6D, 0x90, 0x93, 0x46, 0xE0, 0x04, +0xF0, 0x01, 0xC3, 0x22, 0xFA, 0xF9, 0xF8, 0xC3, 0x02, 0x43, 0xD4, 0x75, 0xF0, 0x0A, 0xA4, 0x24, +0x0A, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x09, 0xF5, +0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0xEF, 0x24, 0xFC, 0x60, 0x05, 0x04, 0x70, 0x05, 0x80, +0x04, 0x12, 0x81, 0x22, 0x22, 0xE4, 0x90, 0x93, 0x47, 0xF0, 0x90, 0x94, 0x6F, 0x04, 0xF0, 0x90, +0x06, 0x32, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x93, 0x12, 0x12, 0x43, 0xE5, 0x12, 0xA1, 0x40, 0xE4, +0x3D, 0xFD, 0xE4, 0x3C, 0xFC, 0x90, 0x93, 0x12, 0x12, 0x08, 0x6D, 0x12, 0x9E, 0xFB, 0xE4, 0x90, +0x94, 0x53, 0xF0, 0xFF, 0x12, 0x9F, 0x6D, 0x12, 0x73, 0x13, 0x70, 0x28, 0x31, 0xF3, 0x7F, 0x05, +0x7E, 0x00, 0x12, 0x3D, 0xC2, 0x12, 0x4E, 0xA9, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x02, 0x60, 0x14, +0x90, 0x93, 0x47, 0xE0, 0x04, 0xF0, 0x12, 0xA1, 0x39, 0x31, 0xF3, 0x90, 0x93, 0x47, 0xE0, 0xD3, +0x94, 0x0A, 0x40, 0xE4, 0x90, 0x94, 0xE5, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x0A, 0x12, 0x83, +0x95, 0x01, 0x4C, 0x7D, 0x01, 0x7F, 0x02, 0x80, 0x04, 0x7D, 0x01, 0x7F, 0x04, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x2F, 0xED, 0xF0, 0x90, 0x8E, 0x11, 0xE0, 0xFE, 0xC4, 0x13, +0x13, 0x54, 0x03, 0x30, 0xE0, 0x02, 0x61, 0x47, 0xEE, 0x12, 0x79, 0x1A, 0x30, 0xE0, 0x02, 0x61, +0x47, 0x90, 0x8E, 0x18, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0x61, 0x47, 0xEF, 0x70, 0x02, 0x41, 0xBE, +0x24, 0xFE, 0x70, 0x02, 0x41, 0xF8, 0x24, 0xFE, 0x60, 0x4B, 0x24, 0xFC, 0x70, 0x02, 0x61, 0x34, +0x24, 0xFC, 0x60, 0x02, 0x61, 0x47, 0xEE, 0xB4, 0x0E, 0x02, 0x71, 0x67, 0x90, 0x8E, 0x18, 0xE0, +0x70, 0x05, 0x7F, 0x01, 0x12, 0x9B, 0x6C, 0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x06, 0x02, 0x71, 0x83, +0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x04, 0x0F, 0x90, 0x95, 0x2F, 0xE0, 0xFF, 0x60, 0x05, 0x12, 0x9B, +0x11, 0x80, 0x03, 0x12, 0x77, 0x5E, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x08, 0x60, 0x02, 0x61, 0x47, +0x12, 0x4F, 0xEF, 0x61, 0x47, 0x90, 0x8E, 0x18, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x9B, 0x6C, +0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x06, 0x02, 0x71, 0x83, 0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x0E, 0x07, +0x71, 0x4C, 0xBF, 0x01, 0x02, 0x71, 0x67, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x0C, 0x60, 0x02, 0x61, +0x47, 0x71, 0x4C, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x61, 0x47, 0x71, 0xA5, 0x61, 0x47, 0x90, 0x8E, +0x18, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0x4C, 0xBF, 0x01, 0x02, 0x71, 0x67, 0x90, 0x8E, 0x18, 0xE0, +0xB4, 0x06, 0x02, 0x71, 0x83, 0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x0C, 0x07, 0x71, 0x4C, 0xBF, 0x01, +0x02, 0x71, 0xA5, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x04, 0x70, 0x5C, 0x12, 0x9A, 0x5D, 0xEF, 0x64, +0x01, 0x70, 0x54, 0x12, 0x9B, 0x43, 0x80, 0x4F, 0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x0E, 0x07, 0x71, +0x4C, 0xBF, 0x01, 0x02, 0x71, 0x67, 0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x06, 0x02, 0x71, 0x83, 0x90, +0x8E, 0x18, 0xE0, 0xB4, 0x0C, 0x07, 0x71, 0x4C, 0xBF, 0x01, 0x02, 0x71, 0xA5, 0x90, 0x8E, 0x18, +0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x9B, 0x6C, 0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x04, 0x18, 0x12, +0x9B, 0x5E, 0x80, 0x13, 0x90, 0x8E, 0x18, 0xE0, 0xB4, 0x0C, 0x0C, 0x90, 0x8E, 0x12, 0x12, 0x67, +0xED, 0x30, 0xE0, 0x03, 0x12, 0x9D, 0x2E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x9A, 0x44, 0xBF, +0x01, 0x12, 0x12, 0xA0, 0x70, 0x20, 0xE0, 0x0C, 0x90, 0x8E, 0x17, 0xE0, 0xD3, 0x94, 0x04, 0x50, +0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x8E, 0x12, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04, +0x7D, 0x0C, 0x80, 0x05, 0x12, 0xA0, 0x87, 0x7D, 0x04, 0x7F, 0x01, 0x12, 0x4E, 0xB5, 0xE4, 0xFD, +0xFF, 0x80, 0x56, 0x90, 0x8E, 0x12, 0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, 0x08, 0xE0, 0x44, 0x40, +0xF0, 0x7D, 0x04, 0x80, 0x06, 0xE0, 0x54, 0x7F, 0xF0, 0x7D, 0x0C, 0x7F, 0x01, 0x12, 0x4E, 0xB5, +0xE4, 0xFD, 0xFF, 0x80, 0x34, 0x12, 0x73, 0x13, 0x70, 0x25, 0x90, 0x8E, 0x12, 0xE0, 0x54, 0xFD, +0xF0, 0x7D, 0x2C, 0x7F, 0x6F, 0x71, 0xD9, 0x7D, 0x08, 0x7F, 0x01, 0x12, 0x65, 0x59, 0xBF, 0x01, +0x0E, 0x90, 0x8E, 0x11, 0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E, 0x7F, 0x01, 0x12, 0x4E, 0xB5, 0x22, +0xE4, 0xFD, 0x7F, 0x0C, 0x31, 0xFD, 0xE4, 0xFD, 0xFF, 0x90, 0x05, 0x22, 0xEF, 0xF0, 0x90, 0x8D, +0x05, 0xED, 0xF0, 0x22, 0x90, 0x93, 0x73, 0x12, 0x44, 0x12, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x93, +0x84, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x0A, 0x7D, 0x39, 0x12, 0x8F, 0xCB, 0xBF, 0x01, 0x10, +0x80, 0x00, 0x90, 0x93, 0x1A, 0x12, 0x64, 0x32, 0x90, 0x93, 0x81, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, +0x90, 0x93, 0x81, 0x12, 0x97, 0xC4, 0x90, 0x93, 0x83, 0xEF, 0xF0, 0x90, 0x93, 0x81, 0x12, 0x9F, +0xF1, 0x90, 0x93, 0x7F, 0xE0, 0xFD, 0x12, 0x98, 0x0A, 0x90, 0x93, 0x80, 0xE0, 0x60, 0x02, 0x81, +0xBF, 0xD1, 0x8B, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x93, 0x76, 0xD1, 0x7A, 0x75, 0x43, +0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0xB1, 0x5D, 0x12, 0x9F, 0xFD, 0xC0, +0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x93, 0x73, 0xD1, 0x7A, 0x75, 0x43, 0x10, 0xD0, 0x01, 0xD0, +0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0xB1, 0x5D, 0xD1, 0x8E, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, +0xD1, 0x77, 0x75, 0x43, 0x10, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0xB1, 0x5D, +0x24, 0x60, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0xD1, +0x77, 0x75, 0x43, 0x10, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0xB1, 0x5D, 0x24, +0x72, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x93, +0x7C, 0xD1, 0x7A, 0x75, 0x43, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, +0x93, 0x79, 0x12, 0x44, 0x09, 0x90, 0x93, 0xB0, 0x12, 0x44, 0x12, 0x90, 0x93, 0xB3, 0x12, 0x08, +0x79, 0x00, 0x00, 0x00, 0x20, 0x90, 0x93, 0xB7, 0x74, 0x3A, 0xF0, 0x90, 0x93, 0x73, 0x12, 0x44, +0x09, 0x12, 0x99, 0x40, 0xB1, 0x5D, 0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC, 0xF1, 0x04, 0x75, 0x43, +0x28, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x85, 0x12, 0x35, 0x26, 0xB1, 0x5D, 0x12, 0xA0, 0xCB, 0xC0, +0x03, 0x8B, 0x40, 0x75, 0x41, 0x8F, 0x75, 0x42, 0x68, 0x75, 0x43, 0x28, 0xD0, 0x03, 0x12, 0x35, +0x26, 0x90, 0x93, 0x83, 0xE0, 0xFF, 0x90, 0x93, 0x82, 0xE0, 0x2F, 0xFF, 0x90, 0x93, 0x81, 0xE0, +0x34, 0x00, 0xCF, 0x24, 0x30, 0xFD, 0xE4, 0x3F, 0xFC, 0x90, 0x93, 0x1A, 0xE0, 0xFB, 0x7F, 0x3A, +0x12, 0x62, 0x1B, 0xB1, 0x5D, 0x12, 0xA0, 0xCB, 0xC0, 0x03, 0x8B, 0x40, 0x75, 0x41, 0x93, 0x75, +0x42, 0x85, 0x75, 0x43, 0x28, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, 0x06, 0x33, 0xE0, 0x44, 0x02, +0xF0, 0x90, 0x93, 0x84, 0xE0, 0xFF, 0x7D, 0x3A, 0x71, 0xD9, 0x02, 0x58, 0x01, 0x90, 0x93, 0x81, +0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0x2F, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, +0xA9, 0x12, 0x44, 0x12, 0x78, 0xB5, 0x7C, 0x94, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x64, +0xF1, 0xF5, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x94, 0xB4, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x0A, +0x7D, 0x33, 0x12, 0x8F, 0xCB, 0xBF, 0x01, 0x10, 0x80, 0x00, 0x90, 0x93, 0x19, 0x12, 0x64, 0x32, +0x90, 0x94, 0xB1, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x94, 0xB1, 0x12, 0x97, 0xC4, 0x90, 0x94, +0xB3, 0xEF, 0xF0, 0x90, 0x94, 0xB1, 0x12, 0x9F, 0xF1, 0x90, 0x94, 0xAF, 0xE0, 0xFD, 0x12, 0x98, +0x0A, 0x90, 0x94, 0xB0, 0xE0, 0x70, 0x4E, 0xD1, 0x8B, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, +0x94, 0xAC, 0xD1, 0x7A, 0x75, 0x43, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xD1, 0x84, 0xB1, +0x60, 0xF1, 0xEE, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x94, 0xAC, 0xD1, +0x7A, 0x75, 0x43, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0xD1, 0x84, 0xB1, 0x60, 0x12, 0x9F, +0xFD, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x94, 0xA9, 0xD1, 0x7A, 0x75, 0x43, 0x04, 0xD0, +0x01, 0xD0, 0x02, 0x80, 0x45, 0x90, 0x94, 0xB0, 0xE0, 0x64, 0x01, 0x70, 0x42, 0xD1, 0x8B, 0xC0, +0x03, 0x8B, 0x40, 0x75, 0x41, 0x8E, 0x75, 0x42, 0xE4, 0x75, 0x43, 0x06, 0xD0, 0x03, 0xD1, 0x84, +0xB1, 0x60, 0xF1, 0xEE, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0x8B, 0x40, 0x75, 0x41, 0x8E, 0x75, 0x42, +0xEE, 0x75, 0x43, 0x06, 0xD0, 0x03, 0xD1, 0x84, 0xB1, 0x60, 0x12, 0x9F, 0xFD, 0xC0, 0x03, 0x8B, +0x40, 0x75, 0x41, 0x8E, 0x75, 0x42, 0xF4, 0x75, 0x43, 0x04, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, +0x06, 0x30, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x94, 0xB4, 0xE0, 0xFF, 0x7D, 0x34, 0x71, 0xD9, 0x12, +0x58, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x93, 0x79, 0x12, 0x44, 0x09, 0x8B, 0x40, 0x8A, +0x41, 0x89, 0x42, 0x22, 0x12, 0x35, 0x26, 0x90, 0x94, 0xB1, 0x22, 0xA3, 0xA3, 0xE0, 0x24, 0x38, +0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0xF1, 0xC8, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, +0x93, 0x4A, 0x12, 0x97, 0xC4, 0x90, 0x93, 0x4C, 0xEF, 0xF0, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0x24, +0x38, 0xF9, 0xE4, 0x34, 0xFC, 0xF1, 0x04, 0x75, 0x43, 0x06, 0x7B, 0x01, 0x7A, 0x8E, 0x79, 0xE4, +0xF1, 0xE7, 0xB1, 0x60, 0x24, 0x3E, 0xF9, 0xE4, 0x34, 0xFC, 0xF1, 0x04, 0x75, 0x43, 0x04, 0x7B, +0x01, 0x7A, 0x8E, 0x79, 0xEA, 0xF1, 0xE7, 0xB1, 0x60, 0xF1, 0xEE, 0xF1, 0x04, 0x75, 0x43, 0x06, +0x7B, 0x01, 0x7A, 0x8E, 0x79, 0xEE, 0xF1, 0xE7, 0xB1, 0x60, 0x24, 0x48, 0xF9, 0xE4, 0x34, 0xFC, +0xF1, 0x04, 0x75, 0x43, 0x04, 0x7B, 0x01, 0x7A, 0x8E, 0x79, 0xF4, 0x02, 0x35, 0x26, 0x24, 0x00, +0xF9, 0xE4, 0x34, 0xFC, 0x75, 0x40, 0x01, 0xF5, 0x41, 0x89, 0x42, 0x22, 0x90, 0x93, 0x23, 0xF1, +0xC6, 0xEF, 0xF0, 0xE0, 0xFE, 0x24, 0x28, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFF, +0x74, 0x29, 0x2E, 0x12, 0x65, 0xC6, 0xFD, 0x90, 0x93, 0x4A, 0xE0, 0x24, 0x2C, 0x12, 0x97, 0xE1, +0x90, 0x93, 0x4A, 0xE0, 0x2F, 0x24, 0x30, 0xA3, 0xF0, 0xE0, 0xFD, 0x24, 0x04, 0x12, 0x66, 0xE7, +0xE0, 0xFE, 0x74, 0x05, 0x2D, 0x12, 0x66, 0xDB, 0x12, 0x84, 0xA3, 0x90, 0x90, 0x7E, 0xF0, 0xA3, +0xEF, 0xF0, 0x90, 0x93, 0x4B, 0xE0, 0x24, 0x0C, 0xF9, 0xE4, 0x34, 0xFC, 0xF1, 0x04, 0x75, 0x43, +0x04, 0x7B, 0x01, 0x7A, 0x90, 0x79, 0x80, 0x12, 0x35, 0x26, 0x90, 0x93, 0x4B, 0xE0, 0x24, 0x14, +0xF0, 0xE0, 0xFD, 0x24, 0x01, 0x12, 0x63, 0xE8, 0xE0, 0xFE, 0x74, 0x00, 0x2D, 0x12, 0x5A, 0xFC, +0x12, 0x84, 0xA3, 0x90, 0x90, 0x84, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0x24, 0xF1, 0xC6, 0xEF, +0xF0, 0x90, 0x90, 0x7A, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x4E, 0x60, 0x11, 0x90, 0x93, 0x4A, 0xE0, +0xD1, 0xFE, 0x8F, 0x43, 0x7B, 0x01, 0x7A, 0x90, 0x79, 0x88, 0x12, 0x35, 0x26, 0x90, 0x93, 0x25, +0xF1, 0xC6, 0xEF, 0xF0, 0xD1, 0xFE, 0x90, 0x90, 0x7C, 0xA3, 0xE0, 0xF5, 0x43, 0x7B, 0x01, 0x7A, +0x90, 0x79, 0xA8, 0x02, 0x35, 0x26, 0xE0, 0xFF, 0xF1, 0xD3, 0x90, 0x93, 0x4A, 0x22, 0x90, 0x8D, +0xFD, 0xE0, 0xFF, 0xE4, 0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, 0x30, 0xE0, 0x02, 0x7E, 0x80, 0x90, +0xFD, 0x10, 0xED, 0xF0, 0xAF, 0x06, 0x22, 0x12, 0x35, 0x26, 0x90, 0x93, 0x4A, 0x22, 0x24, 0x42, +0xF9, 0xE4, 0x34, 0xFC, 0x22, 0x7E, 0x00, 0x7F, 0x06, 0x02, 0x06, 0x63, 0xEE, 0xF0, 0xA3, 0xEF, +0xF0, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x93, 0x54, 0x12, 0x96, 0x66, 0x90, 0x93, 0x6C, 0x74, 0x18, 0xF0, 0x7E, 0x00, 0x7F, 0x80, 0x7D, +0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x74, 0x12, 0x08, 0xAA, 0x90, 0x01, 0xC4, 0x74, 0x08, 0xF0, +0x74, 0x58, 0xA3, 0xF0, 0x90, 0x93, 0x1B, 0xE0, 0xFF, 0x12, 0x57, 0xD3, 0x90, 0x93, 0x6B, 0xEF, +0xF0, 0xF9, 0xE0, 0xFE, 0x24, 0x29, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x74, 0x41, 0xF0, +0xEE, 0x24, 0x28, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x93, 0x6C, 0xE0, 0x7A, 0x00, 0x2D, 0xFE, 0xEA, +0x3C, 0x90, 0x93, 0x70, 0xF0, 0xA3, 0xCE, 0xF0, 0x74, 0x28, 0x29, 0x12, 0x9F, 0xF5, 0x90, 0x93, +0x56, 0xE0, 0xFD, 0x12, 0x98, 0x0A, 0x12, 0x9F, 0xDD, 0x90, 0x93, 0x70, 0xE0, 0xFF, 0xA3, 0xE0, +0x90, 0x93, 0x6E, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0x74, 0x74, 0x01, 0xF0, 0xA3, 0x74, +0x03, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x5F, 0xF0, 0x90, 0x93, 0x70, 0x12, 0x94, 0x41, 0x90, +0x8F, 0xDE, 0xE0, 0xFF, 0x7E, 0x02, 0xB4, 0xFE, 0x02, 0x7E, 0xFE, 0x90, 0x93, 0x70, 0xA3, 0xE0, +0xFD, 0x51, 0xFA, 0xEE, 0xF0, 0x74, 0x00, 0x2D, 0x51, 0xFC, 0xE0, 0x90, 0x93, 0x78, 0xF0, 0x90, +0x93, 0x70, 0x12, 0x61, 0x77, 0x90, 0x90, 0x73, 0xE0, 0x90, 0x93, 0x54, 0xB4, 0x01, 0x0B, 0xE0, +0x44, 0x03, 0xFC, 0xA3, 0xE0, 0x44, 0x10, 0xFD, 0x80, 0x09, 0xE0, 0x44, 0x03, 0xFC, 0xA3, 0xE0, +0x44, 0x20, 0xFD, 0x90, 0x93, 0x72, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x93, 0x79, 0x74, 0x03, +0xF0, 0xA3, 0x74, 0x12, 0xF0, 0x12, 0xA0, 0xB6, 0xEF, 0x64, 0xFE, 0x70, 0x27, 0x90, 0x93, 0x70, +0xA3, 0xE0, 0x24, 0x00, 0x12, 0x9A, 0x24, 0xC0, 0x03, 0x8B, 0x40, 0x12, 0xA0, 0xD5, 0xD0, 0x03, +0x12, 0x35, 0x26, 0x75, 0x40, 0x01, 0x12, 0xA0, 0xD5, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x7B, 0x12, +0x35, 0x26, 0x80, 0x58, 0x90, 0x93, 0x16, 0xE0, 0xFF, 0xB4, 0x02, 0x27, 0x90, 0x93, 0x70, 0xE0, +0xFC, 0xA3, 0xE0, 0xFD, 0x24, 0x00, 0xF5, 0x82, 0x74, 0xFC, 0x3C, 0xF5, 0x83, 0xE4, 0xF0, 0x74, +0x01, 0x2D, 0xF5, 0x82, 0x74, 0xFC, 0x3C, 0xF5, 0x83, 0x74, 0x20, 0x12, 0xA1, 0x58, 0x74, 0x20, +0xF0, 0x80, 0x29, 0xEF, 0xB4, 0x04, 0x25, 0x90, 0x93, 0x70, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x24, +0x00, 0xF5, 0x82, 0x74, 0xFC, 0x3E, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x01, 0x2F, 0xF5, 0x82, 0x74, +0xFC, 0x3E, 0xF5, 0x83, 0x74, 0x10, 0x12, 0xA1, 0x58, 0x74, 0x10, 0xF0, 0x12, 0xA0, 0xB6, 0xE4, +0x90, 0x93, 0x6D, 0xF0, 0x12, 0xA0, 0x07, 0xFE, 0x90, 0x93, 0x70, 0xA3, 0xE0, 0xFD, 0xEF, 0x2D, +0x51, 0xFA, 0xEE, 0xF0, 0x12, 0xA0, 0x07, 0xFE, 0x74, 0x7D, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x93, +0xF5, 0x83, 0xEE, 0xF1, 0xBF, 0xE0, 0xB4, 0x08, 0xDB, 0x12, 0x9F, 0xE7, 0x90, 0x93, 0x70, 0xF1, +0xF6, 0x90, 0x93, 0x70, 0xE4, 0x75, 0xF0, 0x10, 0x12, 0x08, 0xD6, 0x12, 0x9F, 0xDD, 0xE4, 0x90, +0x93, 0xF7, 0xF0, 0xE4, 0x90, 0x93, 0x6D, 0xF0, 0x12, 0xA0, 0xFC, 0x50, 0x0A, 0x12, 0x8F, 0xAA, +0x51, 0xF9, 0xE4, 0xF1, 0xBF, 0x80, 0xF1, 0x7F, 0x64, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0x90, 0x06, +0x31, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x93, 0x1C, 0xE0, 0xFD, 0x12, 0x9A, 0x18, 0xCE, 0xC3, 0x13, +0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0xAC, 0x7B, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xED, 0xFF, 0x90, +0x93, 0x1B, 0xE0, 0xC3, 0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE, 0xEF, 0x78, 0x07, 0xC3, 0x33, 0xCE, +0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x93, 0x6C, 0xE0, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x3E, 0xCF, +0x24, 0x38, 0xCF, 0x34, 0x00, 0xFE, 0x90, 0xAC, 0x7A, 0x74, 0x10, 0xF0, 0x7B, 0x63, 0xE4, 0xFD, +0x12, 0x39, 0x9C, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x74, 0x90, 0xAC, 0xA0, 0x12, 0x44, 0x12, 0x7A, +0x93, 0x79, 0x57, 0x90, 0xAC, 0xA3, 0x12, 0x44, 0x12, 0x90, 0xAC, 0xA6, 0x74, 0x10, 0xF0, 0x7A, +0x8F, 0x79, 0x9A, 0x12, 0x35, 0x86, 0x90, 0x93, 0xF7, 0xE0, 0x04, 0xF0, 0x90, 0x06, 0x31, 0xE0, +0x30, 0xE2, 0x07, 0x12, 0xA1, 0x50, 0x50, 0x02, 0x21, 0xC3, 0x12, 0xA1, 0x50, 0x40, 0x0A, 0x90, +0x06, 0x35, 0xE0, 0x44, 0x20, 0x90, 0x06, 0x34, 0xF0, 0xE4, 0x90, 0x93, 0x6D, 0xF0, 0x12, 0xA0, +0xFC, 0x50, 0x1C, 0x12, 0x8F, 0xAA, 0x90, 0x93, 0x6D, 0xE0, 0x24, 0x57, 0xF5, 0x82, 0xE4, 0x34, +0x93, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x93, 0x6B, 0x51, 0xF9, 0xEF, 0xF1, 0xBF, 0x80, 0xDF, 0x90, +0x04, 0x1D, 0xE0, 0x60, 0x22, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x93, 0xF6, 0xF0, 0x7D, 0x1D, 0x12, +0x8F, 0xCB, 0xBF, 0x01, 0x06, 0x12, 0x64, 0x2F, 0x12, 0xA0, 0x3E, 0x90, 0x93, 0xF6, 0xE0, 0xFF, +0x7D, 0x1E, 0x12, 0x53, 0xD9, 0x80, 0x06, 0x12, 0x64, 0x2F, 0x12, 0xA0, 0x3E, 0x11, 0x01, 0x90, +0x8E, 0x18, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x9B, 0x6C, 0x74, 0x08, 0x04, 0x90, 0x01, 0xC4, +0xF0, 0x74, 0x58, 0xA3, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x42, 0x90, 0xA8, 0x04, 0xA9, +0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, +0xFC, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x93, 0x4A, 0xF0, +0xA3, 0xF0, 0x90, 0x02, 0x09, 0xE0, 0x90, 0x93, 0x4F, 0xF0, 0x90, 0x93, 0x26, 0xE0, 0xFF, 0x12, +0x57, 0xD3, 0x7E, 0x00, 0x90, 0x93, 0x4A, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x51, 0xFA, 0xE0, 0x90, +0x90, 0xCA, 0xF0, 0x74, 0x01, 0x2F, 0x12, 0x63, 0xE8, 0xE0, 0x90, 0x90, 0xCB, 0xF0, 0x90, 0x01, +0xA0, 0xF0, 0x90, 0x93, 0x4A, 0x12, 0x94, 0x41, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0x24, 0x02, 0x12, +0x67, 0x56, 0xFF, 0xE4, 0xFC, 0xFD, 0x78, 0x10, 0x12, 0x08, 0x5A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, +0x06, 0xC0, 0x07, 0xF1, 0xE9, 0xB1, 0x7E, 0x78, 0x18, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, +0xD0, 0x01, 0xD0, 0x00, 0x12, 0x42, 0x90, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xF1, +0xDC, 0xB1, 0x7E, 0x78, 0x08, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, +0x51, 0xEA, 0xB1, 0x80, 0x12, 0x42, 0x90, 0x90, 0x90, 0xCE, 0xB1, 0x65, 0x78, 0x10, 0x12, 0x08, +0x5A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xF1, 0xE9, 0xB1, 0x7E, 0x78, 0x18, 0x12, +0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x42, 0x90, 0xC0, 0x04, 0xC0, +0x05, 0xC0, 0x06, 0xC0, 0x07, 0xF1, 0xDC, 0xB1, 0x7E, 0x78, 0x08, 0x12, 0x08, 0x5A, 0xD0, 0x03, +0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x51, 0xEA, 0xB1, 0x80, 0x12, 0x42, 0x90, 0x90, 0x90, 0xD2, +0xB1, 0x65, 0x78, 0x10, 0x12, 0x08, 0x5A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xF1, +0xE9, 0xB1, 0x7E, 0x78, 0x18, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, +0x12, 0x42, 0x90, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xF1, 0xDC, 0xB1, 0x7E, 0x78, +0x08, 0x12, 0x08, 0x5A, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x51, 0xEA, 0xB1, 0x80, +0x12, 0x42, 0x90, 0x90, 0x90, 0xD6, 0x12, 0x08, 0x6D, 0x90, 0x93, 0x4A, 0xE4, 0x75, 0xF0, 0x04, +0xF1, 0xB6, 0xF1, 0xC7, 0x51, 0xFA, 0xE0, 0xFF, 0x12, 0x96, 0x84, 0xB1, 0x87, 0xE0, 0xB4, 0x10, +0xF1, 0xF1, 0xAF, 0xF1, 0xC7, 0x51, 0xFA, 0xE0, 0xFF, 0x74, 0xEA, 0x2E, 0xF5, 0x82, 0xE4, 0x34, +0x90, 0xB1, 0x87, 0xE0, 0xB4, 0x10, 0xEC, 0xF1, 0xAF, 0xF1, 0xC7, 0x51, 0xFA, 0xE0, 0xFF, 0x74, +0xFA, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xB1, 0x87, 0xE0, 0xB4, 0x10, 0xEC, 0xF1, 0xAF, 0x90, +0x93, 0x4C, 0xE0, 0xFF, 0xC3, 0x94, 0x08, 0x50, 0x1F, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0xFE, 0xEF, +0x2E, 0x51, 0xFA, 0xE0, 0xFE, 0x90, 0x93, 0x4F, 0xE0, 0xFD, 0xEE, 0x2D, 0xFE, 0x74, 0x0A, 0x2F, +0x12, 0x83, 0x8D, 0xEE, 0xB1, 0x8A, 0x80, 0xD7, 0x90, 0x91, 0x0A, 0xE0, 0x90, 0x01, 0xA1, 0xF0, +0x90, 0x91, 0x0B, 0xE0, 0x90, 0x01, 0xA2, 0xF0, 0x90, 0x91, 0x0C, 0xE0, 0x90, 0x01, 0xA3, 0xF0, +0x90, 0x91, 0x0D, 0xE0, 0x90, 0x01, 0xA4, 0xF0, 0x90, 0x91, 0x0E, 0xE0, 0x90, 0x01, 0xA5, 0xF0, +0x90, 0x93, 0x26, 0xE0, 0x04, 0x90, 0x93, 0x4E, 0xF0, 0xE4, 0x90, 0x93, 0x4D, 0xF0, 0x90, 0x90, +0xCA, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x24, 0x01, 0xFF, 0xE4, 0x33, 0xFE, 0x90, 0x93, 0x4D, 0xE0, +0xC3, 0x9F, 0xEE, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x50, 0x63, 0xA3, 0x12, 0x57, 0xC6, 0xE4, +0x12, 0xA1, 0x31, 0x90, 0x93, 0x4C, 0xE0, 0xFD, 0xC3, 0x94, 0x04, 0x50, 0x46, 0xA3, 0xE0, 0x75, +0xF0, 0x04, 0xA4, 0x7C, 0x00, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0xEF, 0x78, 0x05, 0xC3, 0x33, +0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x24, 0x12, 0xF9, 0x74, 0x91, 0x3E, 0xFA, 0x7B, 0x01, 0xC0, 0x03, +0xC0, 0x01, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0x24, 0x00, 0xF9, 0xE4, 0x34, 0xFC, 0x8B, 0x40, 0xF5, +0x41, 0x89, 0x42, 0x75, 0x43, 0x20, 0xD0, 0x01, 0xD0, 0x03, 0x12, 0x57, 0xE7, 0xF1, 0xF6, 0xB1, +0x8B, 0x80, 0xB0, 0x12, 0xA0, 0x50, 0x90, 0x93, 0x4D, 0xE0, 0x04, 0xF0, 0x80, 0x80, 0xE4, 0x90, +0x93, 0x4C, 0xF0, 0xE4, 0xFF, 0x0F, 0xEF, 0xB4, 0x20, 0xFB, 0xB1, 0x8B, 0xE0, 0xB4, 0x10, 0xF3, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x08, 0x6D, 0x90, 0x93, 0x4A, 0xE4, 0x75, 0xF0, 0x04, 0x12, +0x08, 0xD6, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, +0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x93, 0x4C, 0xE0, 0x04, +0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x2A, 0xED, 0xF0, 0xEF, 0x14, +0x60, 0x02, 0xC1, 0x64, 0x90, 0x06, 0x03, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x95, 0x2A, 0xE0, 0xC4, +0x33, 0x54, 0xE0, 0xFF, 0x90, 0x04, 0x42, 0xE0, 0x54, 0x9F, 0x4F, 0xFF, 0xF0, 0x90, 0x94, 0x99, +0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0x94, 0x9D, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, +0x01, 0xF1, 0x30, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0x94, 0x9D, 0x12, 0x08, 0x79, +0x00, 0x00, 0x00, 0x01, 0x7F, 0x00, 0x7E, 0x09, 0xF1, 0x34, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, +0x10, 0x90, 0x95, 0x2A, 0xB1, 0x80, 0xEF, 0x54, 0x03, 0xFF, 0xE4, 0x78, 0x01, 0x12, 0x08, 0x47, +0x78, 0x04, 0xF1, 0xA6, 0x7F, 0x00, 0x7E, 0x0A, 0xF1, 0x34, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, +0x00, 0x90, 0x95, 0x2A, 0xB1, 0x80, 0xEF, 0x54, 0x03, 0xFF, 0xE4, 0x78, 0x0A, 0xF1, 0xA6, 0x7F, +0x00, 0x7E, 0x0D, 0xF1, 0x34, 0x12, 0x08, 0x79, 0x0C, 0x00, 0x00, 0x00, 0x90, 0x95, 0x2A, 0xB1, +0x80, 0xEF, 0x54, 0x03, 0xFF, 0xE4, 0x78, 0x1A, 0xF1, 0xA6, 0x7F, 0x18, 0xF1, 0x32, 0x12, 0x08, +0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0x94, 0x9D, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0xF1, +0xD2, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, 0x94, 0x8B, 0x12, 0x08, 0x79, 0x00, 0x00, +0x04, 0x00, 0x80, 0x58, 0x90, 0x06, 0x03, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x94, 0x99, 0x12, 0x08, +0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0x94, 0x9D, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0xF1, +0x30, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x90, 0x94, 0x9D, 0x12, 0x08, 0x79, 0x00, 0x00, +0x00, 0x00, 0x7F, 0x00, 0x7E, 0x09, 0xF1, 0x34, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x90, +0x94, 0x9D, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0xF1, 0xD2, 0x12, 0x08, 0x79, 0x00, 0x00, +0x0C, 0x00, 0x90, 0x94, 0x8B, 0x12, 0x08, 0x79, 0x00, 0x00, 0x0C, 0x00, 0x7D, 0x18, 0x7C, 0x00, +0xE4, 0xFF, 0x12, 0x82, 0xBE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x58, 0x7E, 0x0C, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, 0x97, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x37, 0x4E, +0x90, 0x94, 0xA1, 0x12, 0x08, 0x6D, 0x90, 0x94, 0x99, 0x12, 0x43, 0xE5, 0x12, 0x08, 0x3A, 0x90, +0x94, 0xA1, 0x12, 0x83, 0x43, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x94, 0x99, +0x12, 0x43, 0xE5, 0x90, 0x94, 0x9D, 0x12, 0x83, 0x43, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, +0x00, 0x12, 0x43, 0xC7, 0x90, 0x94, 0xA5, 0x12, 0x08, 0x6D, 0x90, 0x94, 0xA5, 0x12, 0x61, 0x58, +0x90, 0x94, 0x97, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x38, 0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x7F, 0x00, 0x7E, 0x08, 0xD1, 0xCE, 0x90, 0x94, 0x99, 0x22, 0x90, 0x8D, 0xFB, 0x12, 0x67, 0xED, +0x30, 0xE0, 0x08, 0x12, 0xA1, 0x48, 0xE4, 0x90, 0x94, 0x6E, 0xF0, 0x90, 0x94, 0x99, 0x12, 0x08, +0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, 0x54, 0xB1, 0x80, 0xF1, 0xA9, 0x7F, 0x50, 0x7E, 0x0C, +0xF1, 0x34, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, 0x55, 0xB1, 0x80, 0xF1, 0xA9, +0xD1, 0xCA, 0x90, 0x94, 0x6A, 0xE0, 0x90, 0x06, 0x08, 0xF0, 0x90, 0x94, 0x6C, 0xA3, 0xE0, 0x90, +0x06, 0xA0, 0xF0, 0xA3, 0xE4, 0xF0, 0x90, 0x94, 0x58, 0xE0, 0xFF, 0x60, 0x05, 0xA3, 0xE0, 0xFD, +0xB1, 0x92, 0x90, 0x94, 0x57, 0xE0, 0xFF, 0x60, 0x0C, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0x12, +0x83, 0xA5, 0x12, 0x82, 0x4A, 0x22, 0x12, 0x08, 0x5A, 0x90, 0x94, 0x9D, 0x02, 0x08, 0x6D, 0x90, +0x93, 0x4A, 0xE4, 0x75, 0xF0, 0x10, 0x12, 0x08, 0xD6, 0xE4, 0x90, 0x93, 0x4C, 0xF0, 0x22, 0xF0, +0x90, 0x93, 0x6D, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0xFE, +0x2F, 0x22, 0x7F, 0x84, 0x7E, 0x08, 0xD1, 0xCE, 0x90, 0x94, 0x87, 0x22, 0x90, 0x93, 0x4A, 0xA3, +0xE0, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0x22, 0x90, 0x93, 0x4A, 0xA3, 0xE0, 0x24, 0x03, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0x22, 0xE4, 0x75, 0xF0, 0x20, 0x02, 0x08, 0xD6, 0x75, 0xE8, 0x03, +0x75, 0xA8, 0x85, 0x22, 0xE4, 0x90, 0x93, 0x3C, 0xF0, 0x90, 0x93, 0x3C, 0xE0, 0x64, 0x01, 0xF0, +0x24, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x60, 0xA3, 0xF0, 0x12, 0x3E, 0x44, 0xBF, 0x01, 0x03, +0x12, 0x31, 0xFC, 0xC2, 0xAF, 0x90, 0x8E, 0x15, 0xE0, 0x60, 0x0F, 0x90, 0x8E, 0x18, 0xE0, 0xFF, +0x90, 0x8E, 0x17, 0xE0, 0x6F, 0x60, 0x03, 0x12, 0x74, 0xB2, 0xC2, 0xAF, 0x12, 0x8B, 0xD3, 0xBF, +0x01, 0x02, 0x11, 0x59, 0xD2, 0xAF, 0xD2, 0xAF, 0x90, 0x93, 0x34, 0xE0, 0xB4, 0x01, 0x02, 0x11, +0xF6, 0x12, 0x4F, 0xF8, 0x12, 0x46, 0x38, 0x80, 0xB0, 0x90, 0x8E, 0x11, 0xE0, 0x30, 0xE0, 0x02, +0x11, 0x63, 0x22, 0x90, 0x8E, 0x18, 0xE0, 0xFF, 0x60, 0x03, 0xB4, 0x08, 0x08, 0x12, 0x9A, 0xDB, +0xBF, 0x01, 0x02, 0x11, 0x76, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x4D, 0x0C, +0x11, 0x87, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x90, 0x14, 0x7F, 0x08, 0x12, 0x4A, 0x4E, 0xEF, +0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x49, 0x39, 0xE4, 0xFF, 0x11, 0xA4, 0x90, 0x8E, 0x12, 0xE0, +0x54, 0xEF, 0xF0, 0x22, 0x90, 0x95, 0x17, 0xEF, 0xF1, 0xE6, 0x90, 0x01, 0x09, 0xE0, 0x7F, 0x00, +0x30, 0xE7, 0x02, 0x7F, 0x01, 0x90, 0x95, 0x17, 0xE0, 0x6F, 0x60, 0x39, 0xC3, 0x90, 0x95, 0x19, +0xE0, 0x94, 0x88, 0x90, 0x95, 0x18, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44, +0x10, 0xF0, 0x22, 0x90, 0x95, 0x18, 0x31, 0x77, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0xD3, +0x90, 0x95, 0x19, 0xE0, 0x94, 0x32, 0x90, 0x95, 0x18, 0xE0, 0x94, 0x00, 0x40, 0xBC, 0x90, 0x01, +0xC6, 0xE0, 0x30, 0xE0, 0xB5, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x00, 0x7E, +0x08, 0x12, 0x37, 0x4E, 0x90, 0x93, 0x3D, 0x12, 0x08, 0x6D, 0x7F, 0x00, 0x7E, 0x09, 0x12, 0x37, +0x4E, 0x90, 0x93, 0x41, 0x12, 0x08, 0x6D, 0x90, 0x93, 0x3D, 0x31, 0x6A, 0x60, 0x17, 0x90, 0x93, +0x3D, 0x31, 0x61, 0x90, 0x93, 0x3D, 0x12, 0x08, 0x6D, 0x90, 0x93, 0x3D, 0x31, 0x58, 0x7F, 0x00, +0x7E, 0x08, 0x12, 0x38, 0x45, 0x90, 0x93, 0x41, 0x31, 0x6A, 0x60, 0x17, 0x90, 0x93, 0x41, 0x31, +0x61, 0x90, 0x93, 0x41, 0x12, 0x08, 0x6D, 0x90, 0x93, 0x41, 0x31, 0x58, 0x7F, 0x00, 0x7E, 0x09, +0x12, 0x38, 0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x43, 0xE5, 0x90, 0xAA, 0xB9, 0x02, 0x08, +0x6D, 0x12, 0x43, 0xE5, 0xEF, 0x54, 0xFE, 0xFF, 0xEC, 0x22, 0x12, 0x43, 0xE5, 0xEF, 0x54, 0x01, +0xFF, 0xE4, 0xFE, 0xFD, 0xFC, 0xEF, 0x22, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x08, 0xD6, 0xAD, 0x07, +0x90, 0x90, 0x7E, 0x31, 0x77, 0x90, 0x90, 0x7E, 0xE0, 0xFF, 0xAE, 0x05, 0x74, 0x04, 0x2E, 0xD1, +0xE7, 0xEF, 0xF0, 0x90, 0x90, 0x7E, 0xA3, 0xE0, 0xFF, 0x74, 0x05, 0x2E, 0xD1, 0xDB, 0xEF, 0xF0, +0x22, 0xE4, 0x90, 0x93, 0xFB, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x20, 0xF0, 0x12, +0x8F, 0x6B, 0xEF, 0x64, 0x01, 0x70, 0x63, 0x90, 0x93, 0x23, 0xE0, 0xFF, 0x7B, 0x08, 0x7D, 0x01, +0x91, 0x38, 0x12, 0xA0, 0xF3, 0x90, 0x93, 0xF8, 0x12, 0x97, 0xC4, 0x90, 0x93, 0xFA, 0xEF, 0xF0, +0x90, 0x93, 0xF8, 0x12, 0x9F, 0xF1, 0xE4, 0xFD, 0x12, 0x98, 0x0A, 0x90, 0x93, 0xFA, 0xE0, 0xFF, +0x90, 0x93, 0xF9, 0xE0, 0x2F, 0xFF, 0x90, 0x93, 0xF8, 0xE0, 0x34, 0x00, 0xCF, 0x24, 0x30, 0xCF, +0x34, 0x00, 0xFE, 0x90, 0x93, 0xFB, 0xF0, 0xA3, 0xEF, 0xF0, 0x31, 0x7E, 0x91, 0x1B, 0x90, 0x93, +0x23, 0xE0, 0xFB, 0xE4, 0xFF, 0x51, 0x1B, 0x91, 0x1B, 0x90, 0x93, 0x1F, 0xE0, 0xFB, 0x7F, 0x11, +0x51, 0x1B, 0x12, 0x58, 0x01, 0x90, 0x90, 0x86, 0x31, 0x77, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0x90, 0x94, 0xC9, 0xEC, 0x12, 0x83, 0x9D, 0xAA, 0x07, 0x90, 0x94, 0xD0, 0x12, 0x08, +0x79, 0x00, 0x00, 0x00, 0x00, 0x91, 0x24, 0xEA, 0x24, 0xEF, 0x60, 0x3C, 0x24, 0xD7, 0x70, 0x02, +0x61, 0x7A, 0x24, 0x3A, 0x60, 0x02, 0x61, 0xB3, 0x71, 0xF0, 0x24, 0x0A, 0x71, 0xFF, 0xED, 0xF0, +0xFE, 0x12, 0x5A, 0xFA, 0x71, 0xE3, 0xE4, 0xF0, 0xFE, 0x74, 0x00, 0x2F, 0x91, 0x13, 0x7D, 0x14, +0x71, 0xCC, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x71, 0xD7, 0x90, 0xAC, 0x6A, 0x12, 0x08, 0x6D, +0x7D, 0x14, 0x7C, 0x00, 0xE4, 0xFF, 0x61, 0x75, 0x90, 0x94, 0xC9, 0xE4, 0x75, 0xF0, 0x14, 0x12, +0x08, 0xD6, 0x90, 0x94, 0xC9, 0xA3, 0xE0, 0xFB, 0xFF, 0x24, 0x06, 0xFC, 0x91, 0x00, 0xCC, 0xF0, +0x90, 0x94, 0xD4, 0xA3, 0xE0, 0xFE, 0x12, 0x5A, 0xFA, 0x71, 0xE3, 0xE4, 0xD1, 0xE3, 0xE0, 0xFE, +0xA9, 0x03, 0x74, 0x05, 0x29, 0xD1, 0xDB, 0x12, 0x84, 0xA3, 0xFE, 0x90, 0x94, 0xCE, 0xF0, 0xA3, +0xEF, 0xF0, 0x90, 0x94, 0xC9, 0xE0, 0xFC, 0xA3, 0xE0, 0x2F, 0xFF, 0xEC, 0x3E, 0xFE, 0xD3, 0xEF, +0x94, 0x00, 0xEE, 0x94, 0x01, 0x90, 0x94, 0xC9, 0x40, 0x69, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE9, +0x7C, 0x00, 0x24, 0x00, 0xF9, 0xEC, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xC3, 0xE4, 0x9F, 0xFD, 0x74, +0x01, 0x9E, 0xFC, 0x71, 0xCE, 0x90, 0x94, 0xCB, 0xE0, 0x24, 0x01, 0xFF, 0xE4, 0x33, 0xA2, 0xE7, +0x13, 0xEF, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x91, 0x0D, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, +0x03, 0x7B, 0x01, 0x7A, 0xFC, 0x79, 0x00, 0x90, 0x94, 0xC9, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, +0xE4, 0x9F, 0xFF, 0x74, 0x01, 0x9E, 0xFE, 0x71, 0xF7, 0xC3, 0x9F, 0xFD, 0xEC, 0x9E, 0xFC, 0x12, +0x26, 0x4E, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x42, 0x90, 0x71, 0xD1, 0x91, +0x24, 0x80, 0x0D, 0xA3, 0xE0, 0x7E, 0x00, 0x24, 0x00, 0x91, 0x13, 0x71, 0xF7, 0xFD, 0x71, 0xCE, +0x90, 0x94, 0xC9, 0x74, 0xFF, 0x75, 0xF0, 0xEC, 0x12, 0x08, 0xD6, 0x71, 0xF0, 0x7E, 0x00, 0x24, +0x0C, 0xF9, 0xEE, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xC0, 0x02, 0xC0, 0x01, 0x74, 0x10, 0x2F, 0xF9, +0xEE, 0x34, 0xFC, 0xFA, 0x71, 0xD7, 0x90, 0xAC, 0x6A, 0x12, 0x08, 0x6D, 0x71, 0xF7, 0xFD, 0xD0, +0x01, 0xD0, 0x02, 0x7F, 0x11, 0x12, 0x1B, 0xAC, 0x80, 0x31, 0x71, 0xF0, 0x24, 0x2A, 0x71, 0xFF, +0xED, 0xF0, 0xFE, 0x12, 0x5A, 0xFA, 0x71, 0xE3, 0xE4, 0xF0, 0x12, 0x9A, 0x21, 0x7D, 0x48, 0x71, +0xCC, 0x71, 0xDD, 0x91, 0x08, 0x12, 0x42, 0x90, 0xE4, 0xFD, 0xFC, 0x71, 0xD1, 0x71, 0xDD, 0x91, +0x08, 0x12, 0x42, 0x90, 0x71, 0xD1, 0x71, 0xDD, 0x12, 0x08, 0x3A, 0x90, 0x94, 0xCC, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0x90, 0x94, 0xCC, 0x12, 0xA1, 0x98, 0x90, 0x94, 0xD4, 0xA3, 0xE0, 0xFE, 0x12, +0x5A, 0xFA, 0xEF, 0x71, 0xE4, 0xED, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7C, 0x00, 0x12, 0x26, +0x4E, 0x90, 0x94, 0xD0, 0x02, 0x08, 0x6D, 0x90, 0xAC, 0x67, 0x12, 0x44, 0x12, 0x90, 0x94, 0xD0, +0x02, 0x43, 0xE5, 0xE4, 0xF0, 0x74, 0x01, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, +0x90, 0x94, 0xC9, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x94, 0xCE, 0xE0, 0xFC, 0xA3, 0xE0, 0x22, 0xFD, +0xE4, 0x33, 0x90, 0x94, 0xD4, 0xF0, 0xA3, 0x22, 0x78, 0x10, 0x12, 0x08, 0x47, 0x90, 0x94, 0xD0, +0x02, 0x43, 0xF1, 0xF9, 0xEE, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0x90, 0x93, 0xFB, 0xE0, 0xFC, +0xA3, 0xE0, 0xFD, 0x22, 0x90, 0x94, 0xCB, 0xE0, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x22, 0x90, +0x93, 0x1B, 0xE0, 0xFF, 0x7B, 0x18, 0x7D, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x95, 0x15, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x95, 0x14, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0xF1, +0x7C, 0x90, 0x95, 0x14, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, 0x95, 0x15, 0xE0, 0x60, 0x05, 0xB1, +0xF0, 0x44, 0x80, 0xF0, 0xAF, 0x05, 0x74, 0x20, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, +0xE0, 0x54, 0xC0, 0xF0, 0xB1, 0xF0, 0x54, 0xC0, 0xF0, 0x90, 0x00, 0x8B, 0xE0, 0xD3, 0x94, 0x03, +0x74, 0x10, 0x40, 0x07, 0x91, 0xC2, 0x74, 0x04, 0xF0, 0x80, 0x04, 0x91, 0xC2, 0xE4, 0xF0, 0xAF, +0x05, 0x91, 0xCB, 0xE0, 0x54, 0x01, 0xFE, 0x90, 0x95, 0x16, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB, +0xEE, 0x44, 0x02, 0x4B, 0xFE, 0x91, 0xCB, 0xEE, 0xF0, 0x74, 0x11, 0x2F, 0xF1, 0x4E, 0x74, 0xFF, +0xF0, 0x74, 0x29, 0x2F, 0xB1, 0xC6, 0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x74, 0x12, 0x2F, 0xF5, 0x82, +0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90, 0x8D, 0x09, 0xE0, 0xFF, 0x90, 0x94, 0xF1, 0xE0, 0xFB, +0x7D, 0x01, 0x91, 0x38, 0x90, 0x94, 0xF2, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x94, +0xF0, 0xE0, 0xFF, 0xB1, 0xA4, 0x90, 0x94, 0xF2, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x81, 0x00, +0xE0, 0x54, 0x0F, 0xFD, 0xAC, 0x07, 0xB1, 0xE4, 0x44, 0x01, 0xF0, 0xB1, 0xE4, 0x54, 0xFB, 0xF0, +0xAC, 0x07, 0x74, 0x12, 0x2C, 0x91, 0xCE, 0xE0, 0x44, 0xFA, 0xF0, 0x74, 0x11, 0x2C, 0xF1, 0x4E, +0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF1, 0x45, 0x44, 0x0E, 0xF0, 0x90, 0x04, +0xA7, 0xE4, 0xF0, 0x90, 0x04, 0xA6, 0xF0, 0x90, 0x04, 0xA5, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0xA4, +0x74, 0xFD, 0xF0, 0x74, 0x14, 0x2C, 0xB1, 0xDC, 0xE0, 0x54, 0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F, +0xB1, 0xDC, 0xED, 0xF0, 0x22, 0x7D, 0x08, 0xE4, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x94, 0xF0, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x8D, 0x03, 0xE0, 0x04, 0xF0, 0x90, 0x04, +0x1D, 0xE0, 0x60, 0x22, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x94, 0xF4, 0xF0, 0x7D, 0x26, 0x12, 0x8F, +0xCB, 0xEF, 0x64, 0x01, 0x70, 0x02, 0x91, 0xD6, 0x90, 0x94, 0xF4, 0xE0, 0xFF, 0x7D, 0x27, 0x12, +0x53, 0xD9, 0xB1, 0xFC, 0x80, 0x04, 0xB1, 0xFC, 0x91, 0xD6, 0x12, 0x58, 0x01, 0x7F, 0x01, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0xB1, 0xD0, 0x54, 0x3F, 0xF0, 0xEF, 0x60, 0x0D, 0x74, 0x29, 0x2D, 0xB1, +0xC6, 0x44, 0x10, 0xB1, 0xCF, 0x44, 0x80, 0xF0, 0x22, 0x74, 0x29, 0x2D, 0xB1, 0xC6, 0x54, 0xEF, +0xB1, 0xCF, 0x44, 0x40, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF0, +0x74, 0x09, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF5, 0x82, 0xE4, 0x34, +0xFC, 0xF5, 0x83, 0x22, 0x74, 0x0D, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, +0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x90, 0x94, 0xF0, 0xE0, +0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x31, 0xEF, 0xF0, 0x90, 0x8D, 0x09, +0xE0, 0xFF, 0x90, 0x04, 0x1C, 0xE0, 0x6F, 0x70, 0x3D, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x0E, 0x70, +0x14, 0x90, 0x95, 0x31, 0xE0, 0x70, 0x2F, 0x90, 0x8E, 0x11, 0xE0, 0x54, 0x7F, 0xF0, 0xF1, 0xF4, +0x12, 0x4F, 0xD9, 0x80, 0x1E, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x06, 0x70, 0x19, 0x90, 0x95, 0x31, +0xE0, 0x60, 0x13, 0x90, 0x8E, 0x11, 0xE0, 0x54, 0xBF, 0xF0, 0x12, 0xA0, 0x87, 0x90, 0x8E, 0x18, +0x74, 0x04, 0xF0, 0x12, 0x4F, 0xE9, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xFD, 0xFC, 0x90, 0x93, +0x22, 0xF1, 0x7A, 0xAB, 0x05, 0x74, 0x01, 0x2B, 0x71, 0xE8, 0xE0, 0xFE, 0x74, 0x00, 0x2B, 0x12, +0x5A, 0xFC, 0x12, 0xA0, 0x35, 0x90, 0x90, 0x74, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x03, 0x2B, 0xF1, +0x5F, 0xFE, 0x74, 0x02, 0x2B, 0xF1, 0x56, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x90, 0x90, 0x76, 0xF0, +0xA3, 0xEF, 0xF0, 0x74, 0x05, 0x2B, 0xD1, 0xDB, 0xE0, 0xFE, 0x74, 0x04, 0x2B, 0xD1, 0xE7, 0xE0, +0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x90, 0x90, 0x78, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x07, 0x2B, 0xF1, +0x71, 0xFE, 0x74, 0x06, 0x2B, 0xF1, 0x45, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x90, 0x90, 0x7A, 0xF0, +0xA3, 0xEF, 0xF0, 0x74, 0x09, 0x2B, 0xB1, 0xD3, 0xFE, 0x74, 0x08, 0x2B, 0xF1, 0x68, 0x24, 0x00, +0xFF, 0xEC, 0x3E, 0x90, 0x90, 0x7C, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0xF5, 0x83, 0x22, 0xF0, 0x74, 0x04, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x12, +0x57, 0xCE, 0x74, 0x00, 0x2F, 0x12, 0x5A, 0xFC, 0xE0, 0x90, 0x94, 0x56, 0xF0, 0x74, 0x01, 0x2F, +0x71, 0xE8, 0xE0, 0x90, 0x94, 0x57, 0xF0, 0x74, 0x02, 0x2F, 0xF1, 0x56, 0x90, 0x94, 0x58, 0xF0, +0x74, 0x03, 0x2F, 0xF1, 0x5F, 0x90, 0x94, 0x59, 0xD1, 0xE3, 0xE0, 0x90, 0x94, 0x5A, 0xF0, 0x74, +0x05, 0x2F, 0xD1, 0xDB, 0xE0, 0x90, 0x94, 0x5B, 0xF0, 0x74, 0x06, 0x2F, 0xF1, 0x45, 0x90, 0x94, +0x5C, 0xF0, 0x74, 0x07, 0x2F, 0xF1, 0x71, 0x90, 0x94, 0x5D, 0xF0, 0x74, 0x08, 0x2F, 0xF1, 0x68, +0x90, 0x94, 0x5E, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF5, 0x82, +0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, +0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xE0, 0xFF, 0x12, 0x57, 0xD3, 0x7C, +0x00, 0xAD, 0x07, 0x22, 0xF1, 0xAC, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x0C, 0x60, 0x05, 0x12, 0x53, +0xD0, 0xB1, 0x55, 0x22, 0x90, 0x93, 0x28, 0xF1, 0xED, 0x30, 0xE0, 0x0E, 0x7B, 0x00, 0x7A, 0x00, +0x79, 0x00, 0x12, 0xA0, 0x7A, 0x04, 0xF0, 0x02, 0x55, 0x67, 0xA1, 0x55, 0x12, 0xA0, 0x70, 0x30, +0xE0, 0x05, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0, 0x90, 0x01, 0x3C, +0x74, 0x04, 0xF0, 0xE4, 0x90, 0x94, 0xE2, 0xF0, 0x90, 0x8E, 0xBB, 0xE0, 0xC3, 0x13, 0x54, 0x7F, +0x90, 0x94, 0xE3, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x12, 0x50, 0x18, 0x90, 0x8E, +0x11, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xE0, 0xFF, 0x13, +0x13, 0x54, 0x3F, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x22, 0xE4, 0xFB, 0xFA, 0xFD, +0x7F, 0x01, 0x12, 0x48, 0x39, 0x90, 0x93, 0x45, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x8D, 0x01, 0xE0, +0xFF, 0x70, 0x04, 0xA3, 0xE0, 0x60, 0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE1, 0x0A, 0x90, 0x8D, 0x01, +0xE0, 0x54, 0xFD, 0xF0, 0x12, 0x88, 0x5C, 0xF1, 0xA9, 0x30, 0xE2, 0x06, 0x54, 0xFB, 0xF0, 0x12, +0x83, 0xD9, 0xF1, 0xA9, 0x30, 0xE4, 0x0B, 0x54, 0xEF, 0xF0, 0x12, 0x90, 0xB9, 0xBF, 0x01, 0x02, +0x11, 0x51, 0xF1, 0xA9, 0x30, 0xE7, 0x06, 0x54, 0x7F, 0xF0, 0x12, 0x50, 0xBE, 0xD2, 0xAF, 0x80, +0xBB, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x94, 0x79, 0x12, 0xA1, 0x80, 0xA3, +0x12, 0x67, 0xE6, 0x90, 0x94, 0x81, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0xC4, 0x74, 0x51, +0xF0, 0x74, 0x68, 0xA3, 0xF0, 0x12, 0xA1, 0x0E, 0x12, 0x84, 0xA3, 0x90, 0x94, 0x70, 0xF0, 0xA3, +0xEF, 0xF0, 0x90, 0x02, 0x82, 0xE0, 0x90, 0x94, 0x78, 0xF0, 0x90, 0x8E, 0xC4, 0xE0, 0x20, 0xE0, +0x02, 0x61, 0x3B, 0xE4, 0x90, 0x94, 0x77, 0xF0, 0x90, 0x94, 0x78, 0xE0, 0xFF, 0x90, 0x94, 0x77, +0xE0, 0xC3, 0x9F, 0x40, 0x02, 0x61, 0x3B, 0x90, 0x94, 0x70, 0x12, 0xA1, 0x98, 0x90, 0xFD, 0x11, +0xF0, 0x90, 0x94, 0x81, 0xEF, 0xF0, 0x12, 0x85, 0x37, 0x12, 0xA0, 0x35, 0x54, 0x3F, 0xFE, 0x90, +0x94, 0x72, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x94, 0x7D, 0xEE, 0x12, 0x86, 0x01, 0xE0, 0x54, 0x03, +0xFE, 0xEF, 0x24, 0x18, 0x2E, 0xFF, 0x90, 0x94, 0x82, 0xF0, 0x90, 0x94, 0x71, 0xE0, 0x2F, 0xFF, +0x90, 0x94, 0x70, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x94, 0x74, 0xF1, 0xEB, 0xC0, 0x07, 0x71, 0x4C, +0x7D, 0x01, 0x71, 0x77, 0xC0, 0x07, 0x71, 0x4C, 0x7D, 0x04, 0x71, 0x77, 0xAB, 0x07, 0xD0, 0x05, +0xD0, 0x07, 0x12, 0x97, 0xEA, 0x90, 0x94, 0x79, 0xEF, 0x71, 0x4B, 0xE4, 0xFD, 0x71, 0x77, 0xEF, +0x54, 0xFC, 0x90, 0x94, 0x76, 0xF0, 0x90, 0x94, 0x82, 0xE0, 0xFF, 0x90, 0x94, 0x72, 0xE4, 0x8F, +0xF0, 0x12, 0x08, 0xD6, 0x90, 0x94, 0x72, 0x12, 0x85, 0xDA, 0x90, 0x94, 0x72, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0x90, 0x94, 0x70, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x7D, 0x0F, 0x71, 0x77, 0x90, 0x94, +0x72, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x90, 0x94, 0x70, 0xEC, 0x8D, 0xF0, 0x12, 0xA1, 0x90, 0xFC, +0xA3, 0xE0, 0xFD, 0xD3, 0x90, 0x94, 0x71, 0xE0, 0x9D, 0x90, 0x94, 0x70, 0xE0, 0x9C, 0x40, 0x18, +0x90, 0x8D, 0xF9, 0xE0, 0x24, 0x01, 0xFD, 0x12, 0xA0, 0x5B, 0xFC, 0xC3, 0x90, 0x94, 0x71, 0xE0, +0x9D, 0xF0, 0x90, 0x94, 0x70, 0xE0, 0x9C, 0xF0, 0xEF, 0x30, 0xE6, 0x06, 0x90, 0x01, 0xC7, 0x74, +0x22, 0xF0, 0xEF, 0x30, 0xE7, 0x06, 0x90, 0x01, 0xC7, 0x74, 0x21, 0xF0, 0xEF, 0x30, 0xE5, 0x06, +0x90, 0x01, 0xC7, 0x74, 0x23, 0xF0, 0x90, 0x94, 0x6F, 0xE0, 0x60, 0x3B, 0x90, 0x94, 0x76, 0xE0, +0x24, 0xB0, 0x60, 0x16, 0x24, 0xD0, 0x60, 0x02, 0x41, 0xD7, 0x12, 0xA1, 0x88, 0x20, 0xE0, 0x18, +0x12, 0x89, 0xA1, 0x20, 0xE0, 0x02, 0x41, 0xD7, 0x80, 0x0E, 0x12, 0xA1, 0x88, 0x20, 0xE0, 0x08, +0x12, 0x89, 0xA1, 0x20, 0xE0, 0x02, 0x41, 0xD7, 0x71, 0x4C, 0x90, 0x94, 0x7D, 0xE0, 0xFC, 0xA3, +0xE0, 0xFD, 0x12, 0x94, 0x48, 0x41, 0xD7, 0x90, 0x94, 0x76, 0xE0, 0x24, 0x40, 0x60, 0x04, 0x24, +0x20, 0x70, 0x2A, 0x90, 0x8E, 0xC7, 0x12, 0x79, 0x18, 0x20, 0xE0, 0x02, 0x41, 0xD7, 0x90, 0x8E, +0xDA, 0xE0, 0x04, 0x71, 0x4B, 0x12, 0x91, 0x3C, 0xEF, 0x70, 0x02, 0x41, 0xD7, 0x90, 0x94, 0x76, +0xE0, 0xFF, 0x12, 0x91, 0x2A, 0x90, 0x8E, 0xDB, 0xE0, 0x04, 0xF0, 0x41, 0xD7, 0xF1, 0xFA, 0x30, +0xE0, 0x59, 0x90, 0x94, 0x79, 0xE0, 0xFF, 0x90, 0x94, 0x75, 0xE0, 0x2F, 0xFF, 0x90, 0x94, 0x74, +0xE0, 0x34, 0x00, 0xCF, 0x24, 0x08, 0xCF, 0x34, 0x00, 0xFE, 0x90, 0x94, 0x7F, 0xF1, 0xEB, 0xEF, +0x64, 0x45, 0x70, 0x37, 0xB1, 0x58, 0x12, 0x96, 0xB5, 0xEF, 0x64, 0x01, 0x70, 0x2D, 0xB1, 0x58, +0xF1, 0xB3, 0xEF, 0x64, 0x01, 0x70, 0x24, 0x90, 0x94, 0x83, 0x04, 0xB1, 0x57, 0xA3, 0xE0, 0xFD, +0x12, 0x97, 0x33, 0xEF, 0x70, 0x0D, 0x90, 0x94, 0x81, 0xE0, 0xFD, 0x90, 0xFD, 0x11, 0xB1, 0x57, +0x12, 0x96, 0xEF, 0x90, 0x94, 0x81, 0xE0, 0x90, 0xFD, 0x11, 0xF0, 0x71, 0x4C, 0x12, 0x91, 0x3C, +0xEF, 0x60, 0x1F, 0x71, 0x4C, 0x90, 0x94, 0x79, 0xE0, 0xFD, 0x90, 0x94, 0x7C, 0xE0, 0xFB, 0x90, +0x94, 0x81, 0xE0, 0x90, 0x93, 0x4A, 0xF0, 0x71, 0xA6, 0xEF, 0x60, 0x06, 0x90, 0x94, 0x83, 0x74, +0x01, 0xF0, 0x90, 0x8E, 0xC4, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x12, 0x71, 0x4C, 0x90, 0x94, 0x79, +0xE0, 0xFD, 0x91, 0x2B, 0xEF, 0x60, 0x06, 0x90, 0x94, 0x83, 0x74, 0x01, 0xF0, 0x12, 0x7F, 0x44, +0x54, 0x3F, 0x30, 0xE0, 0x0A, 0x71, 0x4C, 0x90, 0x94, 0x79, 0xE0, 0xFD, 0x12, 0x94, 0x97, 0x90, +0x8E, 0xC4, 0x12, 0x79, 0x18, 0x30, 0xE0, 0x0F, 0x90, 0x94, 0x83, 0xE0, 0x70, 0x09, 0x71, 0x4C, +0x90, 0x94, 0x79, 0xE0, 0xFD, 0xD1, 0xEE, 0x12, 0x99, 0x7F, 0xEF, 0x64, 0x01, 0x60, 0x07, 0x90, +0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x05, 0x7F, 0x01, 0x12, 0x79, 0x21, 0x12, 0x91, 0x04, 0xEF, 0x64, +0x01, 0x70, 0x37, 0x90, 0x8E, 0xDC, 0xE0, 0x04, 0xF0, 0x12, 0x90, 0xEE, 0xAD, 0x07, 0xEF, 0x64, +0x01, 0x60, 0x1F, 0xF1, 0x98, 0xED, 0xB4, 0x02, 0x08, 0x90, 0x01, 0xC7, 0x74, 0x42, 0xF0, 0x80, +0x0A, 0xED, 0xB4, 0x04, 0x06, 0x90, 0x01, 0xC7, 0x74, 0x43, 0xF0, 0x7F, 0x01, 0x12, 0x79, 0x21, +0x80, 0x19, 0x90, 0x94, 0x70, 0x12, 0x90, 0xA6, 0x80, 0x09, 0x90, 0x8E, 0xC4, 0xE0, 0x54, 0xFE, +0xF0, 0x80, 0x08, 0x90, 0x94, 0x77, 0xE0, 0x04, 0xF0, 0x01, 0x98, 0x74, 0x51, 0x04, 0x90, 0x01, +0xC4, 0xF0, 0x74, 0x68, 0xA3, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90, 0x94, 0x74, 0xE0, +0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x93, 0x48, 0xE0, 0xFD, 0x90, 0x93, 0x47, 0xE0, 0x2D, 0xFD, +0x90, 0x93, 0x46, 0xE0, 0x34, 0x00, 0xCD, 0x24, 0x10, 0xCD, 0x34, 0x00, 0xFC, 0x7E, 0x00, 0xED, +0x2F, 0xFF, 0xEE, 0x3C, 0xFE, 0xE4, 0xFD, 0xAB, 0x07, 0xAA, 0x06, 0xED, 0x2B, 0xFB, 0xE4, 0x3A, +0xFA, 0xC3, 0x90, 0x8D, 0xF9, 0xE0, 0x9B, 0x90, 0x8D, 0xF8, 0xE0, 0x9A, 0x50, 0x0C, 0xA3, 0x12, +0xA0, 0x57, 0xFE, 0xC3, 0xEB, 0x9F, 0xFB, 0xEA, 0x9E, 0xFA, 0x12, 0xA1, 0x60, 0x74, 0x00, 0x2F, +0x12, 0x85, 0x46, 0xE0, 0xFF, 0x22, 0x90, 0x93, 0x48, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x12, 0x91, +0x95, 0x90, 0x93, 0x4B, 0xF0, 0xFD, 0x71, 0x77, 0xEF, 0x54, 0x0C, 0x64, 0x08, 0x70, 0x5C, 0x91, +0x22, 0xA3, 0xE0, 0xF1, 0x90, 0x64, 0x88, 0x70, 0x52, 0x91, 0x22, 0xA3, 0xE0, 0x24, 0x07, 0xFD, +0x71, 0x77, 0xEF, 0x64, 0x8E, 0x70, 0x44, 0x90, 0x93, 0x4B, 0x04, 0x91, 0x21, 0x12, 0xA0, 0xAB, +0x04, 0xFD, 0x71, 0x77, 0xEF, 0x64, 0x03, 0x70, 0x32, 0x91, 0x22, 0x12, 0xA0, 0xAB, 0xF1, 0x90, +0x30, 0xE3, 0x07, 0x90, 0x01, 0xC7, 0x74, 0x01, 0x80, 0x1F, 0x90, 0x8E, 0xC4, 0x12, 0xA0, 0x73, +0x30, 0xE0, 0x09, 0x91, 0x22, 0xA3, 0xE0, 0xFD, 0xB1, 0x78, 0x80, 0x0F, 0x90, 0x8E, 0xC7, 0xF1, +0xFD, 0x30, 0xE0, 0x07, 0x90, 0x01, 0xC7, 0x74, 0x02, 0xF1, 0x97, 0x90, 0x93, 0x4B, 0xE0, 0xFF, +0x22, 0xF0, 0x90, 0x93, 0x46, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x12, 0x96, 0x63, 0x12, 0x96, +0x9F, 0x7A, 0x40, 0x79, 0x56, 0x12, 0x57, 0xF5, 0x78, 0x55, 0x7C, 0x93, 0x7D, 0x01, 0x7B, 0xFF, +0x7A, 0x40, 0x79, 0x5C, 0xF1, 0xE4, 0x78, 0x59, 0x7C, 0x93, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, +0x79, 0x60, 0xF1, 0xE4, 0xE4, 0x90, 0x93, 0x5E, 0xF0, 0xD1, 0xA4, 0xCF, 0x24, 0x06, 0xCF, 0xB1, +0x71, 0xEF, 0x64, 0x08, 0x60, 0x02, 0xA1, 0x4A, 0xD1, 0xA4, 0xCF, 0x24, 0x07, 0xCF, 0xB1, 0x71, +0xEF, 0x64, 0x06, 0x60, 0x02, 0xA1, 0x4A, 0x90, 0x93, 0x5E, 0x04, 0xF0, 0xE4, 0x90, 0x93, 0x5D, +0xF0, 0xB1, 0x50, 0x94, 0x06, 0x50, 0x17, 0x90, 0x93, 0x47, 0xE0, 0x24, 0x0A, 0xFD, 0x90, 0x93, +0x46, 0xE0, 0x71, 0x6A, 0x90, 0x93, 0x5D, 0x12, 0x96, 0x96, 0xB1, 0x61, 0x80, 0xE3, 0xF1, 0xF3, +0x7B, 0x01, 0x7A, 0x8E, 0x79, 0xD4, 0x12, 0x91, 0x8C, 0x60, 0x02, 0xA1, 0x4A, 0x90, 0x93, 0x5D, +0xF0, 0xB1, 0x50, 0x94, 0x04, 0x50, 0x19, 0x12, 0x96, 0x6F, 0xD1, 0xAF, 0xCD, 0x24, 0x20, 0x71, +0x69, 0x90, 0x93, 0x5D, 0xE0, 0x24, 0x59, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xB1, 0x61, 0x80, 0xE1, +0x78, 0x59, 0x7C, 0x93, 0x12, 0xA0, 0x17, 0xEF, 0x70, 0x67, 0x90, 0x06, 0x30, 0xE0, 0x44, 0x01, +0x54, 0xDF, 0xF0, 0x90, 0x8E, 0xC6, 0xE0, 0x30, 0xE0, 0x09, 0x90, 0x01, 0xC7, 0x74, 0x09, 0xF1, +0x97, 0x80, 0x57, 0xE4, 0x90, 0x93, 0x5D, 0xF0, 0xB1, 0x50, 0x94, 0x06, 0x50, 0x0C, 0x71, 0x55, +0x90, 0x93, 0x5D, 0x12, 0x96, 0x8D, 0xB1, 0x61, 0x80, 0xEE, 0xE4, 0x90, 0x93, 0x5D, 0xF0, 0xB1, +0x50, 0x94, 0x04, 0x50, 0x19, 0x12, 0x96, 0x6F, 0xD1, 0xAF, 0xCD, 0x24, 0x16, 0x71, 0x69, 0x90, +0x93, 0x5D, 0xE0, 0x24, 0x55, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xB1, 0x61, 0x80, 0xE1, 0x7B, 0x01, +0x7A, 0x93, 0x79, 0x4F, 0x12, 0xA0, 0x7A, 0xF0, 0x7A, 0x93, 0x79, 0x55, 0x12, 0x55, 0x67, 0x80, +0x09, 0x90, 0x06, 0x30, 0xE0, 0x44, 0x21, 0x54, 0xEF, 0xF0, 0x90, 0x93, 0x5E, 0xE0, 0xFF, 0x22, +0x90, 0x93, 0x5D, 0xE0, 0xFF, 0xC3, 0x22, 0xF0, 0x90, 0x94, 0x7F, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, +0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x93, 0x5D, 0xE0, 0x04, 0xF0, 0x22, 0xFF, 0x90, 0x93, 0x4F, +0xE0, 0x34, 0x00, 0xFE, 0xE4, 0xFD, 0x61, 0x77, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x06, 0x31, 0xE0, 0x54, 0xEF, 0x44, 0x08, 0xF0, 0xED, 0x2F, 0xFF, 0xE4, 0x3E, 0xFE, 0x7C, 0x00, +0xEF, 0x24, 0x08, 0xFF, 0xEC, 0x3E, 0x90, 0x93, 0x4F, 0xF0, 0xA3, 0xEF, 0xF0, 0x7E, 0x00, 0x7F, +0x83, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0xDA, 0x12, 0x08, 0xAA, 0x90, 0x93, 0x50, 0xE0, +0x24, 0x01, 0xB1, 0x6C, 0x90, 0x8F, 0xDB, 0xD1, 0x9D, 0x24, 0x04, 0xB1, 0x6C, 0x90, 0x8F, 0xDE, +0xD1, 0x9D, 0x24, 0x05, 0xB1, 0x6C, 0x90, 0x8F, 0xDF, 0xD1, 0x9D, 0x24, 0x06, 0xB1, 0x6C, 0x90, +0x8F, 0xE0, 0xD1, 0x9D, 0x24, 0x07, 0xB1, 0x6C, 0x90, 0x8F, 0xE1, 0xD1, 0x9D, 0x24, 0x08, 0xB1, +0x6C, 0x90, 0x8F, 0xE2, 0xEF, 0xF0, 0xE4, 0x90, 0x93, 0x4E, 0xF0, 0x90, 0x93, 0x4E, 0xE0, 0xFF, +0xC3, 0x94, 0x08, 0x50, 0x1D, 0x90, 0x93, 0x50, 0xE0, 0x24, 0x09, 0xFD, 0x90, 0x93, 0x4F, 0xE0, +0x71, 0x6A, 0x90, 0x93, 0x4E, 0xE0, 0x24, 0xE3, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0x12, 0xA0, 0x4C, +0x80, 0xD9, 0xE4, 0x90, 0x93, 0x4E, 0xF0, 0x90, 0x93, 0x4E, 0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x50, +0x1D, 0x90, 0x93, 0x50, 0xE0, 0x24, 0x63, 0xFD, 0x90, 0x93, 0x4F, 0xE0, 0x71, 0x6A, 0x90, 0x93, +0x4E, 0xE0, 0x24, 0x3D, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0x12, 0xA0, 0x4C, 0x80, 0xD9, 0x90, 0x8F, +0xDF, 0x12, 0x9E, 0x47, 0x12, 0xA1, 0x05, 0x30, 0xE3, 0x0D, 0x7F, 0x01, 0x12, 0x79, 0x21, 0x90, +0x01, 0xC7, 0x74, 0x03, 0xF0, 0x80, 0x3F, 0x90, 0x93, 0x4C, 0xA3, 0xE0, 0xFF, 0x7C, 0x00, 0x54, +0x07, 0xFD, 0x64, 0x01, 0x60, 0x05, 0xED, 0x64, 0x02, 0x70, 0x2B, 0xED, 0x64, 0x02, 0x4C, 0x70, +0x25, 0xEF, 0x54, 0x30, 0xFF, 0xE4, 0xC4, 0xF8, 0x54, 0xF0, 0xC8, 0xEF, 0xC4, 0x54, 0x0F, 0x48, +0x90, 0x90, 0x73, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xE4, 0xFD, 0x12, 0x9D, 0x3A, 0x90, 0x06, 0x31, +0xE0, 0x54, 0xF7, 0x44, 0x10, 0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xEF, 0xF0, 0x90, +0x93, 0x50, 0xE0, 0x22, 0x90, 0x93, 0x48, 0xE0, 0xFF, 0x90, 0x93, 0x47, 0xE0, 0x2F, 0xFF, 0x90, +0x93, 0x46, 0xE0, 0x34, 0x00, 0x22, 0x90, 0x93, 0x56, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x7D, 0x09, +0x71, 0x77, 0xEF, 0x64, 0x06, 0x70, 0x24, 0xF1, 0xA0, 0x7D, 0x14, 0x71, 0x77, 0xEF, 0x70, 0x1B, +0xF1, 0xA0, 0x7D, 0x15, 0x71, 0x77, 0xEF, 0x64, 0x50, 0x70, 0x10, 0xF1, 0xA0, 0x7D, 0x21, 0x71, +0x77, 0xEF, 0x20, 0xE0, 0x03, 0x30, 0xE2, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x12, 0x96, +0x63, 0xF1, 0xF3, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x90, 0x12, 0x57, 0xF5, 0x78, 0x50, 0x7C, 0x93, +0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x96, 0xF1, 0xE4, 0x91, 0x22, 0x12, 0x91, 0x3C, 0xEF, +0x60, 0x7D, 0xD1, 0xA4, 0xFE, 0x90, 0x93, 0x54, 0xF0, 0xA3, 0xEF, 0xF0, 0x24, 0x06, 0xFF, 0xE4, +0x3E, 0xB1, 0x73, 0xEF, 0x64, 0x08, 0x70, 0x67, 0x90, 0x93, 0x55, 0xE0, 0x24, 0x07, 0xFF, 0x90, +0x93, 0x54, 0xB1, 0x70, 0xEF, 0x70, 0x58, 0x90, 0x93, 0x4F, 0xF0, 0x90, 0x93, 0x4F, 0xE0, 0xFF, +0xC3, 0x94, 0x04, 0x50, 0x24, 0x90, 0x93, 0x55, 0xE0, 0x24, 0x18, 0xFD, 0x90, 0x93, 0x54, 0xE0, +0x71, 0x6A, 0x90, 0x93, 0x4F, 0xE0, 0x24, 0x50, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xEF, +0xF0, 0x90, 0x93, 0x4F, 0xE0, 0x04, 0xF0, 0x80, 0xD2, 0x78, 0x50, 0x7C, 0x93, 0x12, 0xA0, 0x17, +0xEF, 0x70, 0x1C, 0x90, 0x93, 0x55, 0xE0, 0x24, 0x08, 0xFF, 0x90, 0x93, 0x54, 0xE0, 0x34, 0x00, +0xFE, 0xD1, 0xB6, 0xEF, 0x64, 0x01, 0x60, 0x07, 0x90, 0x01, 0xC7, 0x74, 0x22, 0xF1, 0x97, 0x22, +0x24, 0x06, 0xFD, 0x71, 0x77, 0xEF, 0x22, 0xF0, 0x90, 0x8E, 0xCD, 0xE0, 0x44, 0x01, 0xF0, 0x22, +0x90, 0x93, 0x56, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x8D, 0x01, +0xE0, 0xFF, 0x22, 0x12, 0x96, 0x7B, 0x24, 0x16, 0xFF, 0xE4, 0x3E, 0xB1, 0x73, 0x90, 0x90, 0x84, +0xA3, 0xE0, 0xB5, 0x07, 0x19, 0x90, 0x93, 0x47, 0xE0, 0x24, 0x16, 0xD1, 0xAE, 0xFE, 0x7D, 0x01, +0x71, 0x77, 0xEF, 0xFD, 0x90, 0x90, 0x84, 0xE0, 0x6D, 0x70, 0x01, 0xE4, 0x60, 0x03, 0x7F, 0x00, +0x22, 0x7F, 0x01, 0x22, 0x7E, 0x00, 0x7F, 0x04, 0x02, 0x06, 0x63, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, +0xFD, 0x61, 0x77, 0x78, 0x49, 0x7C, 0x93, 0x7D, 0x01, 0x22, 0x90, 0x8E, 0xC4, 0xE0, 0xC4, 0x13, +0x13, 0x54, 0x03, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, +0x05, 0xC0, 0x07, 0x7D, 0x04, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x70, 0x11, 0x2B, 0xD0, 0x07, +0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xFF, 0xA3, 0xF0, 0xED, 0x04, +0x90, 0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, +0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, 0x38, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x70, +0x11, 0x2B, 0xD0, 0x07, 0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, -0xEF, 0xF0, 0x74, 0x77, 0xA3, 0xF0, 0x12, 0x92, 0x33, 0xE5, 0x21, 0x30, 0xE0, 0x03, 0x12, 0x92, -0xA9, 0xE5, 0x21, 0x30, 0xE1, 0x02, 0x11, 0x7C, 0xE5, 0x21, 0x30, 0xE2, 0x02, 0x11, 0x85, 0xE5, -0x22, 0x30, 0xE0, 0x02, 0xF1, 0x69, 0xE5, 0x24, 0x30, 0xE1, 0x05, 0x7F, 0x04, 0x12, 0x69, 0xEF, -0xE5, 0x24, 0x30, 0xE4, 0x03, 0x12, 0x6E, 0xC4, 0xE5, 0x24, 0x30, 0xE5, 0x02, 0x11, 0x9A, 0xE5, -0x24, 0x30, 0xE6, 0x02, 0x31, 0x05, 0x74, 0xEF, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x77, 0xA3, +0x5F, 0xF0, 0x74, 0x70, 0xA3, 0xF0, 0x12, 0x4B, 0x6E, 0xE5, 0x14, 0x30, 0xE7, 0x03, 0x12, 0x4E, +0x6C, 0x74, 0x5F, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x70, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, +0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, +0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, +0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, +0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xB7, 0xF0, 0x74, 0x70, 0xA3, 0xF0, 0x12, 0x8C, +0x1B, 0xE5, 0x19, 0x30, 0xE3, 0x03, 0x12, 0x8C, 0x78, 0xE5, 0x19, 0x30, 0xE4, 0x02, 0x31, 0xDA, +0xE5, 0x19, 0x30, 0xE5, 0x03, 0x12, 0x8C, 0x85, 0xE5, 0x1B, 0x30, 0xE0, 0x02, 0x31, 0x59, 0xE5, +0x1B, 0x30, 0xE1, 0x03, 0x12, 0x8C, 0xC1, 0xE5, 0x1B, 0x30, 0xE2, 0x03, 0x12, 0x8E, 0x23, 0xE5, +0x1B, 0x30, 0xE3, 0x02, 0x71, 0x1B, 0xE5, 0x1B, 0x30, 0xE4, 0x02, 0x71, 0x57, 0xE5, 0x1B, 0x30, +0xE5, 0x02, 0x71, 0x87, 0xE5, 0x1B, 0x30, 0xE6, 0x02, 0x71, 0x70, 0xE5, 0x1C, 0x30, 0xE1, 0x03, +0x12, 0x8E, 0x35, 0x74, 0xB7, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x70, 0xA3, 0xF0, 0xD0, 0x07, +0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, +0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0xE4, 0xF5, 0x58, 0x90, 0x8E, 0x15, 0xE0, +0x60, 0x6D, 0x71, 0x13, 0x70, 0x69, 0xF1, 0x6C, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x12, +0xA0, 0x9F, 0x90, 0x8E, 0x13, 0xE0, 0xC4, 0x54, 0x0F, 0x60, 0x22, 0x24, 0xFE, 0x60, 0x03, 0x04, +0x70, 0x1E, 0x90, 0x8E, 0x1C, 0xE0, 0x14, 0xF0, 0xE0, 0xFF, 0x60, 0x06, 0x90, 0x8E, 0x1E, 0xE0, +0x60, 0x0E, 0xEF, 0x70, 0x08, 0x90, 0x8E, 0x1B, 0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x75, 0x58, 0x01, +0xE5, 0x58, 0x60, 0x2B, 0x12, 0xA1, 0x78, 0x90, 0x8E, 0x1E, 0xE0, 0x60, 0x03, 0xB4, 0x01, 0x04, +0x31, 0xD0, 0x80, 0x08, 0x31, 0xD0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, 0x90, 0x8E, 0x1D, +0xE0, 0x2F, 0x12, 0x50, 0x0D, 0x90, 0x8E, 0x18, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x51, 0xF9, 0x22, +0xE4, 0x90, 0x94, 0xE2, 0xF0, 0x90, 0x8E, 0x1E, 0xE0, 0x22, 0x31, 0xED, 0x7F, 0x02, 0x8F, 0x59, +0x7F, 0x02, 0x12, 0x48, 0x12, 0x90, 0x8D, 0x01, 0xE0, 0x45, 0x59, 0xF0, 0x22, 0x90, 0x01, 0xCC, +0xE0, 0x54, 0x0F, 0x90, 0x95, 0x1C, 0xF0, 0x90, 0x95, 0x1C, 0xE0, 0xFD, 0x70, 0x02, 0x41, 0xE8, +0x90, 0x8D, 0x5E, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, +0x90, 0x8D, 0x5F, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, +0x90, 0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x95, 0x1A, 0x12, 0x89, 0xA8, 0x80, 0x05, +0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0x41, 0xCA, 0xE4, 0x90, +0x95, 0x1D, 0xF0, 0x90, 0x95, 0x1D, 0xE0, 0xF9, 0xC3, 0x94, 0x04, 0x50, 0x31, 0x51, 0xE9, 0xA4, +0xFF, 0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xD0, 0x71, 0x01, 0x90, +0x8D, 0x0E, 0x51, 0xF1, 0x51, 0xE9, 0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xF0, 0x71, +0x01, 0x90, 0x8D, 0x12, 0x51, 0xF1, 0x90, 0x95, 0x1D, 0xE0, 0x04, 0xF0, 0x80, 0xC5, 0x90, 0x95, +0x1C, 0xE0, 0xFF, 0x90, 0x95, 0x1A, 0x12, 0x4B, 0x14, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, +0x5F, 0x90, 0x95, 0x1C, 0xF0, 0x90, 0x95, 0x1A, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, +0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x95, 0x1A, 0xE0, 0x04, 0xF0, 0xE0, +0x54, 0x03, 0xF0, 0x90, 0x8D, 0x5F, 0x12, 0x83, 0x7E, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x70, +0x02, 0x21, 0xF7, 0xE4, 0x90, 0x8D, 0x5F, 0xF0, 0x21, 0xF7, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x02, +0xF0, 0x90, 0x95, 0x1A, 0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A, 0xF0, 0x51, 0xE9, 0x90, 0x01, 0xD0, +0x12, 0x43, 0xFD, 0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, 0x90, 0x95, 0x1A, 0xE0, 0x75, 0xF0, 0x04, +0x22, 0x12, 0x43, 0xFD, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5, 0x83, 0xEF, 0xF0, +0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x8D, 0x5F, 0xE0, 0x75, +0xF0, 0x08, 0x22, 0xE4, 0xFF, 0x71, 0x2E, 0xEF, 0x64, 0x01, 0x22, 0x71, 0x13, 0x70, 0x0E, 0x90, +0x8E, 0x15, 0xE0, 0x60, 0x08, 0xB1, 0x76, 0x12, 0x9B, 0xE5, 0x12, 0x50, 0x0D, 0x22, 0x12, 0x89, +0xA1, 0xFE, 0xEF, 0x54, 0x07, 0xFF, 0x12, 0x89, 0x3C, 0xE0, 0xFD, 0x7C, 0x00, 0x12, 0x89, 0xAA, +0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF, 0x5D, 0x4E, +0x7F, 0x00, 0x60, 0x02, 0x7F, 0x01, 0x22, 0x71, 0x13, 0x70, 0x14, 0x90, 0x8E, 0x15, 0xE0, 0x60, +0x0E, 0xB1, 0x76, 0x90, 0x8E, 0x11, 0xE0, 0xF1, 0x53, 0x54, 0x07, 0x70, 0x02, 0x91, 0xB2, 0x22, +0xE4, 0xFF, 0x71, 0x2E, 0xBF, 0x01, 0x0F, 0x90, 0x8E, 0x15, 0xE0, 0x60, 0x09, 0x12, 0x9B, 0xDD, +0x54, 0x07, 0x70, 0x02, 0x91, 0xB2, 0x22, 0xE4, 0xFF, 0x71, 0x2E, 0xBF, 0x01, 0x12, 0x90, 0x8E, +0x15, 0xE0, 0x60, 0x0C, 0xF1, 0xF5, 0x64, 0x02, 0x60, 0x03, 0x02, 0x9B, 0xEF, 0x12, 0x67, 0x84, +0x22, 0xE4, 0x90, 0x93, 0xFD, 0xF0, 0x90, 0x8E, 0x15, 0xE0, 0x60, 0x3A, 0x71, 0x13, 0x70, 0x36, +0x12, 0xA1, 0x68, 0xF1, 0x6B, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x12, 0xA0, 0x9F, 0x90, +0x93, 0xFD, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x8E, 0x1C, 0xF0, 0x04, 0x60, 0x19, 0x12, 0xA1, 0x78, +0xE4, 0x90, 0x94, 0xE2, 0xF0, 0x90, 0x8E, 0x1D, 0xE0, 0x12, 0x50, 0x0D, 0x90, 0x8E, 0x18, 0xE0, +0x20, 0xE2, 0x03, 0x12, 0x51, 0xF9, 0x22, 0x8B, 0x51, 0x8A, 0x52, 0x89, 0x53, 0xF1, 0xC3, 0xFF, +0xF5, 0x55, 0x12, 0x06, 0x89, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, 0x7D, 0xB4, 0xF5, 0x56, +0x80, 0x02, 0x8F, 0x56, 0x85, 0x55, 0x54, 0xE5, 0x54, 0xD3, 0x95, 0x56, 0x50, 0x26, 0xAB, 0x51, +0xAA, 0x52, 0xA9, 0x53, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFD, 0xAF, 0x54, 0x12, 0x88, 0xFC, 0xAF, +0x54, 0x71, 0x2E, 0xEF, 0xAF, 0x54, 0x70, 0x05, 0x12, 0x8A, 0x77, 0x80, 0x03, 0x12, 0x8A, 0x63, +0x05, 0x54, 0x80, 0xD3, 0xE5, 0x55, 0x70, 0x0E, 0xFF, 0x71, 0x2E, 0xEF, 0x70, 0x08, 0xB1, 0x69, +0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22, 0xF1, 0x48, 0x30, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x13, +0x54, 0x03, 0x30, 0xE0, 0x02, 0xF1, 0x12, 0x90, 0x8E, 0x11, 0x12, 0x67, 0xED, 0x30, 0xE0, 0x09, +0xEF, 0xF1, 0x53, 0x54, 0x07, 0x70, 0x42, 0x80, 0x3E, 0x90, 0x8E, 0x1E, 0xE0, 0x04, 0xF0, 0x90, +0x8E, 0x19, 0xE0, 0x54, 0xEF, 0xF0, 0x12, 0xA0, 0x93, 0x40, 0x2C, 0x71, 0x13, 0x70, 0x2A, 0xF1, +0xF5, 0x70, 0x04, 0x91, 0xBC, 0x80, 0x23, 0x91, 0xBC, 0x90, 0x8E, 0x1F, 0xE0, 0x04, 0xF0, 0xE0, +0xD3, 0x94, 0x02, 0x40, 0x09, 0x91, 0xAA, 0xE4, 0x90, 0x8E, 0x1F, 0xF0, 0x80, 0x03, 0x12, 0x67, +0x84, 0xE4, 0x90, 0x8E, 0x1E, 0xF0, 0x22, 0x91, 0xB2, 0x22, 0x90, 0x8E, 0x12, 0xE0, 0x54, 0xFB, +0xF0, 0x22, 0x90, 0x8E, 0x17, 0xE0, 0xFF, 0x7D, 0x01, 0x02, 0x51, 0xFD, 0x12, 0xA0, 0x93, 0x40, +0x20, 0x90, 0x8E, 0x2F, 0xE0, 0x04, 0xF0, 0xE0, 0xFF, 0x94, 0x04, 0x50, 0x14, 0x90, 0x8E, 0x27, +0xEF, 0xF0, 0x25, 0xE0, 0x24, 0x08, 0x90, 0x8E, 0x2E, 0xF0, 0xFB, 0x12, 0x8F, 0x1B, 0x12, 0x8E, +0xB0, 0x22, 0x90, 0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x7D, 0x78, 0xFF, 0xB1, +0x25, 0x7D, 0x02, 0x7F, 0x03, 0xB1, 0x25, 0x90, 0x06, 0x0A, 0xE0, 0x44, 0x07, 0x12, 0xA0, 0xC0, +0xE4, 0xFF, 0x71, 0x2E, 0xBF, 0x01, 0x10, 0x91, 0xAA, 0x90, 0x8E, 0x18, 0xE0, 0x20, 0xE2, 0x0A, +0x7D, 0x01, 0x7F, 0x04, 0x02, 0x51, 0xFD, 0x12, 0xA1, 0x70, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0xB1, +0x25, 0x7D, 0x01, 0x7F, 0x02, 0x74, 0x15, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x30, 0xF1, +0x34, 0xF0, 0x22, 0xEF, 0x70, 0x31, 0x7D, 0x78, 0x7F, 0x02, 0xD1, 0x27, 0x7D, 0x02, 0x7F, 0x03, +0xD1, 0x27, 0x7D, 0xC8, 0x7F, 0x02, 0xF1, 0x27, 0xB1, 0x76, 0xE4, 0xFF, 0x71, 0x2E, 0xEF, 0x70, +0x0A, 0xB1, 0x69, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x80, 0x07, 0x7D, 0x01, 0x7F, 0x0C, 0x12, +0x51, 0xFD, 0xB1, 0x6E, 0x02, 0xA1, 0x29, 0x81, 0xE2, 0x12, 0x4D, 0xE7, 0xF1, 0x5E, 0x90, 0x8E, +0x11, 0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, +0xF0, 0x22, 0xF1, 0x6C, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x12, 0xA0, 0xF3, 0x71, +0x13, 0x60, 0x02, 0xC1, 0x1C, 0x90, 0x8E, 0x15, 0xE0, 0x70, 0x02, 0xC1, 0x1C, 0xF1, 0x1E, 0x64, +0x01, 0x70, 0x22, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x8E, 0x1C, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, +0x8E, 0x1B, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x8E, 0x1B, 0xE0, 0xFE, 0xFF, 0x80, 0x00, +0x90, 0x8E, 0x1C, 0xEF, 0xF0, 0x12, 0x9C, 0x08, 0x12, 0xA1, 0x70, 0xE4, 0x90, 0x8E, 0x1E, 0x12, +0xA0, 0xC0, 0xB1, 0x76, 0xF1, 0x56, 0x54, 0xEF, 0xF0, 0xF1, 0x1E, 0x24, 0xFD, 0x50, 0x02, 0x80, +0x03, 0x12, 0x9B, 0x84, 0xF1, 0x48, 0x30, 0xE0, 0x33, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, +0xE0, 0x2A, 0x90, 0x8E, 0x1B, 0xE0, 0xFF, 0xA3, 0xE0, 0x6F, 0x70, 0x20, 0x90, 0x8E, 0x12, 0xE0, +0x44, 0x40, 0xF0, 0x12, 0xA1, 0x68, 0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, +0xD1, 0xC1, 0xD1, 0x23, 0xF1, 0x12, 0x90, 0x8E, 0x1C, 0xE0, 0x14, 0xF0, 0x22, 0x7D, 0x02, 0x7F, +0x02, 0xD1, 0x27, 0x7D, 0x01, 0x7F, 0x02, 0x74, 0x15, 0x12, 0xA1, 0xA0, 0xFE, 0xF6, 0x74, 0x30, +0xF1, 0x34, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x30, 0xEF, 0xF0, +0x54, 0x01, 0xFF, 0x90, 0x8E, 0xC0, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x90, 0x8D, 0xFB, 0xF1, 0x4B, +0x30, 0xE0, 0x39, 0x12, 0x83, 0xC2, 0x60, 0x10, 0x12, 0x83, 0xB8, 0x40, 0x0B, 0xE4, 0x7F, 0x0A, +0xFE, 0xFD, 0xFC, 0x90, 0x90, 0xD6, 0x80, 0x09, 0xE4, 0x7F, 0x0A, 0xFE, 0xFD, 0xFC, 0x90, 0x90, +0xCE, 0x12, 0x43, 0xF1, 0x12, 0x42, 0x9D, 0xC0, 0x07, 0x90, 0x8E, 0xC2, 0xE0, 0xFB, 0xE4, 0xFA, +0xF9, 0xF8, 0xD0, 0x07, 0x12, 0x43, 0x28, 0x90, 0x8E, 0xC3, 0xEF, 0xF0, 0x90, 0x95, 0x30, 0xE0, +0x64, 0x01, 0x70, 0x1F, 0x90, 0x01, 0x53, 0xF0, 0x90, 0x8E, 0xC2, 0xE0, 0x60, 0x0A, 0x7D, 0x10, +0x7F, 0x03, 0xD1, 0xC1, 0xF1, 0x8D, 0x80, 0x14, 0xF1, 0x3E, 0xF1, 0x27, 0xD1, 0x1D, 0x12, 0x9D, +0x2E, 0x80, 0x09, 0xF1, 0x3E, 0xD1, 0xC1, 0xB1, 0x1B, 0x12, 0x4F, 0xEF, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0x74, 0x1D, 0x2F, 0xF8, 0xE6, 0x4D, 0xF1, 0x30, 0xF0, 0x22, 0x90, 0x8E, 0xC0, 0xE0, 0x30, +0xE0, 0x3F, 0xF1, 0x8D, 0x90, 0x8E, 0xC3, 0xE0, 0x60, 0x05, 0x14, 0xF0, 0x02, 0x9D, 0x2E, 0x90, +0x8E, 0xC1, 0xE0, 0x14, 0x90, 0x8E, 0xC3, 0xF0, 0x90, 0x05, 0x73, 0x74, 0x01, 0xF0, 0xE4, 0xFF, +0xD1, 0x34, 0xB1, 0x1B, 0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0x20, 0xE0, 0x08, 0x13, 0x13, 0x13, 0x54, +0x1F, 0x30, 0xE0, 0x0D, 0x90, 0x94, 0xE5, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x01, 0x12, 0x50, +0x45, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0xC1, 0x27, 0x71, 0xA1, 0xF1, 0xBC, 0x80, 0xAD, 0x90, 0x8E, +0x13, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x22, 0x74, 0x1D, 0x12, 0xA1, 0xA0, 0xF1, 0x30, 0xF0, 0x22, +0xFE, 0xF6, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0xEE, 0x22, 0x90, 0x01, +0x53, 0x74, 0x03, 0xF0, 0x7D, 0x10, 0xFF, 0x22, 0x90, 0x8E, 0x12, 0xE0, 0xFF, 0x13, 0x13, 0x13, +0x54, 0x1F, 0x22, 0x54, 0xFB, 0xF0, 0x90, 0x8E, 0x19, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x12, 0x67, +0xF4, 0x12, 0x4F, 0xE9, 0x7D, 0x0C, 0x7F, 0x01, 0x02, 0x4E, 0xB5, 0xF0, 0x90, 0x05, 0x62, 0xE0, +0xFE, 0x90, 0x05, 0x61, 0xE0, 0xFD, 0xED, 0x78, 0x02, 0x22, 0x90, 0x8E, 0xC0, 0xE0, 0x30, 0xE0, +0x0B, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x04, 0xD1, 0x1D, 0xF1, 0x8D, 0x22, 0x90, 0x8E, 0xC2, +0xE0, 0x90, 0x05, 0x73, 0xF0, 0x22, 0x90, 0x8E, 0x11, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0x90, 0x8E, +0x1E, 0xF0, 0xA3, 0xF0, 0x90, 0x8E, 0x19, 0xF0, 0x90, 0x8E, 0x12, 0xE0, 0x54, 0xF7, 0xF0, 0x54, +0xBF, 0xF0, 0xB1, 0x21, 0xF1, 0xBC, 0x7D, 0x10, 0x7F, 0x03, 0xE1, 0x27, 0x7D, 0x02, 0x7F, 0x02, +0xA1, 0x25, 0xF0, 0x90, 0x00, 0x01, 0x02, 0x06, 0xA2, 0x90, 0x93, 0x4D, 0x12, 0x44, 0x12, 0xF1, +0x96, 0x90, 0x8E, 0x15, 0xE0, 0xFF, 0xB1, 0x33, 0x90, 0x8E, 0x15, 0xE0, 0x60, 0x12, 0x90, 0x93, +0x4D, 0x12, 0x44, 0x09, 0xF1, 0xC3, 0x54, 0x0F, 0xFF, 0x12, 0x7D, 0xB4, 0xFD, 0x12, 0x9A, 0xAE, +0x22, 0x7F, 0x80, 0x21, 0xDE, 0x90, 0x8E, 0x13, 0xE0, 0x54, 0x0F, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, +0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, +0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xFC, 0xF0, 0x74, +0x77, 0xA3, 0xF0, 0x12, 0x8C, 0x48, 0xE5, 0x21, 0x30, 0xE0, 0x03, 0x12, 0x77, 0xF1, 0xE5, 0x21, +0x30, 0xE1, 0x03, 0x12, 0x8E, 0x5B, 0xE5, 0x21, 0x30, 0xE2, 0x03, 0x12, 0x8E, 0x65, 0xE5, 0x22, +0x30, 0xE0, 0x03, 0x12, 0x8E, 0x7C, 0xE5, 0x24, 0x30, 0xE1, 0x05, 0x7F, 0x04, 0x12, 0x71, 0xDE, +0xE5, 0x24, 0x30, 0xE4, 0x03, 0x12, 0x77, 0x18, 0xE5, 0x24, 0x30, 0xE5, 0x02, 0x11, 0x8C, 0xE5, +0x24, 0x30, 0xE6, 0x02, 0x11, 0xF1, 0x74, 0xFC, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x77, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, -0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x8E, 0x84, 0xE0, -0x60, 0x02, 0x31, 0x3C, 0x22, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x0E, 0x90, 0x06, 0x92, 0xE0, 0x30, -0xE1, 0x02, 0x21, 0xEE, 0x12, 0x6D, 0x82, 0x31, 0x32, 0x22, 0x90, 0x8E, 0x80, 0x12, 0x9F, 0xD0, -0x30, 0xE0, 0x1A, 0xEF, 0x54, 0xBF, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x8E, 0x81, 0x30, 0xE0, -0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFE, 0xF0, 0x31, 0x32, 0xE4, 0xFF, 0x90, -0x93, 0x8D, 0xE0, 0x30, 0xE0, 0x3E, 0x90, 0x93, 0x92, 0xE0, 0xFD, 0x60, 0x37, 0x12, 0xA0, 0x1F, -0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x04, 0xE0, 0xE0, 0xFB, 0xEF, -0x5B, 0x60, 0x0B, 0xE4, 0x90, 0x93, 0x92, 0xF0, 0x90, 0x93, 0x94, 0x04, 0xF0, 0x22, 0x90, 0x93, -0x8F, 0xE0, 0xD3, 0x9D, 0x50, 0x05, 0x12, 0x9A, 0x0E, 0xF0, 0x22, 0x12, 0x57, 0x83, 0x90, 0x93, -0x92, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x8E, 0x80, 0x12, 0x74, 0x19, 0x30, 0xE0, 0x20, 0xEF, 0x54, -0x7F, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x8E, 0x81, 0x30, 0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, -0x80, 0x04, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x02, 0x31, 0x32, 0x7F, 0x01, -0x80, 0x8D, 0x90, 0x8E, 0x86, 0xE0, 0xFF, 0x7D, 0x01, 0x02, 0x51, 0xEB, 0x90, 0x8E, 0x80, 0x12, -0x84, 0x0B, 0x30, 0xE0, 0x0A, 0xEF, 0x12, 0x9E, 0xD7, 0x54, 0x07, 0x70, 0x20, 0x80, 0x1C, 0x90, -0x8E, 0x8D, 0xE0, 0x04, 0xF0, 0x90, 0x8E, 0x88, 0xE0, 0x54, 0xEF, 0xF0, 0x12, 0x8D, 0x34, 0x40, -0x0A, 0x90, 0x8D, 0xFF, 0xE0, 0xB4, 0x01, 0x05, 0x02, 0x9F, 0xFF, 0x31, 0x32, 0x22, 0x90, 0x8D, -0xFF, 0xE0, 0xB4, 0x01, 0x0E, 0x90, 0x8E, 0x84, 0xE0, 0x60, 0x08, 0x31, 0x84, 0x54, 0x07, 0x70, -0x02, 0x31, 0x32, 0x22, 0x90, 0x8E, 0x88, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0xE4, 0xF5, 0x58, 0x90, -0x06, 0xA9, 0xE0, 0xF5, 0x58, 0x54, 0xC0, 0x70, 0x07, 0x31, 0x84, 0x54, 0xFD, 0xF0, 0x80, 0x92, -0xE5, 0x58, 0x30, 0xE6, 0x1D, 0x90, 0x8E, 0x84, 0xE0, 0x64, 0x01, 0x70, 0x17, 0x90, 0x8E, 0x88, -0xE0, 0x44, 0x01, 0xF0, 0xF1, 0x0A, 0x64, 0x02, 0x60, 0x04, 0x51, 0x2E, 0x80, 0x06, 0x31, 0xDD, -0x80, 0x02, 0x31, 0x84, 0xE5, 0x58, 0x90, 0x8E, 0x88, 0x30, 0xE7, 0x0C, 0xE0, 0x44, 0x02, 0x12, -0x6E, 0xFF, 0x51, 0x24, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x31, 0xEE, 0x90, -0x8E, 0x87, 0xE0, 0x64, 0x0C, 0x60, 0x06, 0x12, 0x54, 0x48, 0x12, 0x57, 0x83, 0x22, 0x90, 0x8E, -0x80, 0x12, 0x9E, 0xBD, 0x30, 0xE0, 0x05, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92, 0x74, -0x02, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, 0xE4, 0x90, 0x95, 0x43, 0xF0, 0x90, 0x8F, 0x25, -0xE0, 0xC3, 0x13, 0x54, 0x7F, 0x90, 0x95, 0x44, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x51, 0x24, -0x44, 0x08, 0xF0, 0x22, 0x7E, 0x01, 0x12, 0x50, 0x02, 0x90, 0x8E, 0x80, 0xE0, 0x22, 0x90, 0x04, -0x1D, 0xE0, 0x70, 0x11, 0x90, 0x8D, 0x08, 0xE0, 0xFF, 0x7B, 0x18, 0xE4, 0xFD, 0x51, 0x64, 0x90, -0x95, 0x87, 0x12, 0x57, 0xE7, 0x22, 0x90, 0x8D, 0xFF, 0xE0, 0xB4, 0x01, 0x10, 0x90, 0x8E, 0x84, -0xE0, 0x60, 0x0A, 0xF1, 0x0A, 0x64, 0x02, 0x60, 0x02, 0x80, 0xD3, 0x31, 0xDD, 0x22, 0xE0, 0xFF, -0x7B, 0x18, 0x7D, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x76, 0xED, 0xF0, -0xA3, 0xEB, 0xF0, 0x90, 0x95, 0x75, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0x12, 0x67, 0xED, 0x90, 0x95, -0x75, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, 0x95, 0x76, 0xE0, 0x60, 0x05, 0xD1, 0xC9, 0x44, 0x80, -0xF0, 0xAF, 0x05, 0x74, 0x20, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, -0xF0, 0xD1, 0xC9, 0x54, 0xC0, 0xF0, 0x90, 0x00, 0x8B, 0xE0, 0xD3, 0x94, 0x03, 0x74, 0x10, 0x40, -0x0D, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x74, 0x04, 0xF0, 0x80, 0x0A, 0x2D, 0xF5, -0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0xAF, 0x05, 0xD1, 0x2A, 0xE0, 0x54, 0x01, 0xFE, -0x90, 0x95, 0x77, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xEE, 0x44, 0x02, 0x4B, 0xFE, 0xD1, 0x2A, -0xEE, 0xF0, 0x74, 0x11, 0x2F, 0xF1, 0x11, 0x74, 0xFF, 0xF0, 0x74, 0x29, 0x2F, 0xD1, 0xF4, 0x54, -0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, -0xC0, 0xD0, 0x90, 0x93, 0xB5, 0x12, 0x97, 0xE4, 0x90, 0x93, 0xCD, 0x74, 0x18, 0xF0, 0x7E, 0x00, -0x7F, 0x80, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xD5, 0x12, 0x08, 0xAA, 0x90, 0x01, 0xC4, -0x74, 0xFB, 0xF0, 0x74, 0x7A, 0xA3, 0xF0, 0x90, 0x93, 0x7C, 0xE0, 0xFF, 0x12, 0x66, 0x4A, 0x90, -0x93, 0xCC, 0xEF, 0xF0, 0xF9, 0xE0, 0xFE, 0x24, 0x29, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, -0x74, 0x41, 0xF0, 0xEE, 0x24, 0x28, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x93, 0xCD, 0xE0, 0x7A, 0x00, -0x2D, 0xFE, 0xEA, 0x3C, 0x90, 0x93, 0xD1, 0xF0, 0xA3, 0xCE, 0xF0, 0x74, 0x28, 0x29, 0x12, 0x8D, -0x20, 0x90, 0x93, 0xB7, 0xE0, 0xFD, 0x12, 0x8B, 0xCD, 0xB1, 0xF2, 0x90, 0x93, 0xD1, 0xE0, 0xFF, -0xA3, 0xE0, 0x90, 0x93, 0xCF, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0xD5, 0x74, 0x01, 0xF0, -0xA3, 0x74, 0x03, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x5F, 0xF0, 0x90, 0x93, 0xD1, 0x12, 0x67, -0xE4, 0x90, 0x90, 0x47, 0xE0, 0xFF, 0x7E, 0x02, 0xB4, 0xFE, 0x02, 0x7E, 0xFE, 0x90, 0x93, 0xD1, -0xA3, 0xE0, 0xFD, 0x12, 0x63, 0x3F, 0xEE, 0xF0, 0x74, 0x00, 0x2D, 0x12, 0x63, 0x41, 0xE0, 0x90, -0x93, 0xD9, 0xF0, 0x90, 0x93, 0xD1, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x08, 0xD6, 0x90, 0x90, 0xDC, -0xE0, 0x90, 0x93, 0xB5, 0xB4, 0x01, 0x0B, 0xE0, 0x44, 0x03, 0xFC, 0xA3, 0xE0, 0x44, 0x10, 0xFD, -0x80, 0x09, 0xE0, 0x44, 0x03, 0xFC, 0xA3, 0xE0, 0x44, 0x20, 0xFD, 0x90, 0x93, 0xD3, 0xEC, 0xF0, -0xA3, 0xED, 0xF0, 0x90, 0x93, 0xDA, 0x74, 0x03, 0xF0, 0xA3, 0x74, 0x12, 0xF0, 0xD1, 0x16, 0xEF, -0x64, 0xFE, 0x70, 0x25, 0x90, 0x93, 0xD1, 0xA3, 0xE0, 0x24, 0x00, 0x12, 0x99, 0x5F, 0xC0, 0x03, -0x8B, 0x40, 0xD1, 0x20, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x75, 0x40, 0x01, 0xD1, 0x20, 0x7B, 0x01, -0x7A, 0x93, 0x79, 0xDC, 0x12, 0x35, 0x26, 0x80, 0x56, 0x90, 0x93, 0x77, 0xE0, 0xFF, 0xB4, 0x02, -0x26, 0x90, 0x93, 0xD1, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x24, 0x00, 0xF5, 0x82, 0x74, 0xFC, 0x3C, -0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0x74, 0xFC, 0x3C, 0xF5, 0x83, 0x74, 0x20, -0xD1, 0x0E, 0x74, 0x20, 0xF0, 0x80, 0x28, 0xEF, 0xB4, 0x04, 0x24, 0x90, 0x93, 0xD1, 0xE0, 0xFE, -0xA3, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0x74, 0xFC, 0x3E, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x01, -0x2F, 0xF5, 0x82, 0x74, 0xFC, 0x3E, 0xF5, 0x83, 0x74, 0x10, 0xD1, 0x0E, 0x74, 0x10, 0xF0, 0xD1, -0x16, 0xE4, 0x90, 0x93, 0xCE, 0xF0, 0xF1, 0x27, 0xFE, 0x90, 0x93, 0xD1, 0xA3, 0xE0, 0xFD, 0xEF, -0x2D, 0x12, 0x63, 0x3F, 0xEE, 0xF0, 0xF1, 0x27, 0xFE, 0x74, 0xDE, 0x2F, 0xF5, 0x82, 0xE4, 0x34, -0x93, 0xF5, 0x83, 0xEE, 0xB1, 0xEA, 0xE0, 0xB4, 0x08, 0xDC, 0xB1, 0xFC, 0x90, 0x93, 0xD1, 0xE4, -0x75, 0xF0, 0x20, 0x12, 0x08, 0xD6, 0x90, 0x93, 0xD1, 0x12, 0x66, 0x79, 0xB1, 0xF2, 0xE4, 0x90, -0x94, 0x58, 0xF0, 0xE4, 0x90, 0x93, 0xCE, 0xF0, 0x90, 0x93, 0xCE, 0xE0, 0xFF, 0xC3, 0x94, 0x10, -0x50, 0x0A, 0xF1, 0x48, 0x12, 0x63, 0x3E, 0xE4, 0xB1, 0xEA, 0x80, 0xEC, 0x7F, 0x64, 0x7E, 0x00, -0x12, 0x3E, 0x50, 0x90, 0x06, 0x31, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x93, 0x7D, 0xE0, 0xFD, 0x75, -0xF0, 0x80, 0xA4, 0xAE, 0xF0, 0x78, 0x03, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, -0xAC, 0x7B, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xED, 0xFF, 0x90, 0x93, 0x7C, 0xE0, 0xC3, 0x9F, 0xFF, -0xE4, 0x94, 0x00, 0xFE, 0xEF, 0x78, 0x07, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, -0x93, 0xCD, 0xE0, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x3E, 0xCF, 0x24, 0x38, 0xCF, 0x34, 0x00, 0xFE, -0x90, 0xAC, 0x7A, 0x74, 0x10, 0xF0, 0x7B, 0x63, 0xE4, 0xFD, 0x12, 0x39, 0x9C, 0x7B, 0x01, 0x7A, -0x93, 0x79, 0xD5, 0x90, 0xAC, 0xA0, 0x12, 0x44, 0x12, 0x7A, 0x93, 0x79, 0xB8, 0x90, 0xAC, 0xA3, -0x12, 0x44, 0x12, 0x90, 0xAC, 0xA6, 0x74, 0x10, 0xF0, 0x7A, 0x90, 0x79, 0x03, 0x12, 0x35, 0x86, -0x90, 0x94, 0x58, 0xE0, 0x04, 0xF0, 0x90, 0x06, 0x31, 0xE0, 0x30, 0xE2, 0x06, 0xD1, 0x06, 0x50, -0x02, 0x81, 0xB3, 0xD1, 0x06, 0x40, 0x0A, 0x90, 0x06, 0x35, 0xE0, 0x44, 0x20, 0x90, 0x06, 0x34, -0xF0, 0xE4, 0x90, 0x93, 0xCE, 0xF0, 0x90, 0x93, 0xCE, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50, 0x1C, -0xF1, 0x48, 0x90, 0x93, 0xCE, 0xE0, 0x24, 0xB8, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xE0, -0xFF, 0x90, 0x93, 0xCC, 0x12, 0x63, 0x3E, 0xEF, 0xB1, 0xEA, 0x80, 0xDA, 0x90, 0x04, 0x1D, 0xE0, -0x60, 0x23, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x94, 0x57, 0xF0, 0x7D, 0x1D, 0x12, 0x57, 0xF8, 0xBF, -0x01, 0x07, 0x90, 0x93, 0x7C, 0x51, 0x5E, 0xF1, 0x19, 0x90, 0x94, 0x57, 0xE0, 0xFF, 0x7D, 0x1E, -0x12, 0x54, 0x51, 0x80, 0x07, 0x90, 0x93, 0x7C, 0x51, 0x5E, 0xF1, 0x19, 0x12, 0x57, 0xEC, 0x90, -0x8E, 0x87, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x53, 0x91, 0x74, 0xFB, 0x04, 0x90, 0x01, 0xC4, -0xF0, 0x74, 0x7A, 0xA3, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90, 0x93, 0xCE, 0xE0, 0x04, -0xF0, 0x22, 0x90, 0x93, 0xD1, 0xE4, 0x75, 0xF0, 0x08, 0x12, 0x08, 0xD6, 0x90, 0x93, 0xD1, 0xE4, -0x75, 0xF0, 0x08, 0x02, 0x08, 0xD6, 0x90, 0x94, 0x58, 0xE0, 0xC3, 0x94, 0x0A, 0x22, 0xF0, 0xE4, -0x90, 0x93, 0xDC, 0xF0, 0xA3, 0x22, 0x90, 0x93, 0xD1, 0xE4, 0x75, 0xF0, 0x02, 0x02, 0x08, 0xD6, -0x75, 0x41, 0x90, 0x75, 0x42, 0x4A, 0x75, 0x43, 0x02, 0x22, 0x74, 0x12, 0x2F, 0xF5, 0x82, 0xE4, -0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90, 0x8D, 0x09, 0xE0, 0xFF, 0x90, 0x95, 0x52, 0xE0, 0xFB, 0x7D, -0x01, 0x51, 0x64, 0x90, 0x95, 0x53, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x95, 0x51, -0xE0, 0xFF, 0xD1, 0xD5, 0x90, 0x95, 0x53, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x81, 0x00, 0xE0, -0x54, 0x0F, 0xFD, 0xAC, 0x07, 0xD1, 0xBD, 0x44, 0x01, 0xF0, 0xD1, 0xBD, 0x54, 0xFB, 0xF0, 0xAC, -0x07, 0x74, 0x12, 0x2C, 0xD1, 0x2D, 0xE0, 0x44, 0xFA, 0xF0, 0x74, 0x11, 0x2C, 0xF1, 0x11, 0xE0, -0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0x12, 0x67, 0xD0, 0x44, 0x0E, 0xF0, 0x90, 0x04, -0xA7, 0xE4, 0xF0, 0x90, 0x04, 0xA6, 0xF0, 0x90, 0x04, 0xA5, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0xA4, -0x74, 0xFD, 0xF0, 0x74, 0x14, 0x2C, 0xD1, 0xB5, 0xE0, 0x54, 0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F, -0xD1, 0xB5, 0xED, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x74, 0x0D, 0x2C, -0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, -0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xD1, 0xFE, 0x54, 0x3F, 0xF0, 0xEF, 0x60, 0x0A, 0xD1, 0xF1, 0x44, -0x10, 0xD1, 0xFD, 0x44, 0x80, 0xF0, 0x22, 0xD1, 0xF1, 0x54, 0xEF, 0xD1, 0xFD, 0x44, 0x40, 0xF0, -0x22, 0x74, 0x29, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF0, 0x74, 0x09, -0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x90, 0x8E, 0x82, 0xE0, 0x54, 0x0F, -0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90, 0x93, 0xCC, 0xEF, 0xF0, 0x90, 0x93, -0x7C, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x22, 0x90, 0x93, 0xCE, 0xE0, 0xFF, 0x24, 0x4C, 0xF5, 0x82, -0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE0, 0x22, 0xC3, 0xEE, 0x94, 0x01, 0x40, 0x0A, 0x0D, 0xED, 0x13, -0x90, 0xFD, 0x10, 0xF0, 0xE4, 0x2F, 0xFF, 0x22, 0x90, 0x93, 0xD2, 0xE0, 0x2F, 0xFF, 0x90, 0x93, -0xD1, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x94, 0x55, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0x7C, 0xE0, -0xFD, 0xF1, 0x37, 0x90, 0x93, 0xCC, 0xEF, 0xF0, 0x22, 0x12, 0x92, 0xAE, 0x90, 0x94, 0x5E, 0xEF, -0xF0, 0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x53, 0xDC, 0x90, -0x94, 0x5E, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80, -0x06, 0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0x12, 0x8D, 0x0A, 0xFD, 0x90, 0x8E, 0x9A, 0xE0, 0xFB, -0xA9, 0x07, 0x90, 0x8E, 0x80, 0xE0, 0x30, 0xE0, 0x45, 0x90, 0x8E, 0xBB, 0xE0, 0x24, 0x03, 0xFF, -0xE4, 0x33, 0xFE, 0x90, 0x8E, 0x96, 0xE0, 0xD3, 0x12, 0x9F, 0xC0, 0x98, 0x50, 0x07, 0x90, 0x8E, -0x8C, 0xEB, 0xF0, 0x80, 0x15, 0xED, 0x24, 0xFD, 0xFF, 0x90, 0x8E, 0xBB, 0xE0, 0x2F, 0x2B, 0x90, -0x8E, 0x8C, 0xF0, 0x90, 0x8E, 0xBB, 0xE0, 0x24, 0x03, 0xFD, 0x90, 0x8E, 0xBB, 0xE0, 0x24, 0x04, -0xC3, 0x9D, 0x29, 0xFF, 0x90, 0x8E, 0x99, 0x12, 0x8A, 0x4B, 0xEF, 0xF0, 0x80, 0x0B, 0x12, 0x8A, -0x4C, 0x74, 0x02, 0xF0, 0x90, 0x8E, 0x8C, 0xEB, 0xF0, 0x90, 0x8E, 0x8F, 0xA3, 0xE0, 0x90, 0x05, -0x58, 0xF0, 0x22, 0x32, 0x90, 0x95, 0x8A, 0x12, 0x88, 0x12, 0x90, 0x8D, 0x01, 0xE0, 0xFF, 0x90, -0x95, 0x8A, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x8D, 0x01, 0xF0, 0x22, 0x90, 0x93, 0xB6, 0x74, 0x12, -0xF0, 0x90, 0x93, 0xC4, 0x74, 0x05, 0xF0, 0x90, 0x93, 0xB8, 0xEF, 0x12, 0xA0, 0x37, 0x90, 0x93, -0xB4, 0xE0, 0x90, 0x93, 0xBB, 0xF0, 0x90, 0x93, 0xB5, 0xE0, 0x90, 0x93, 0xBC, 0xF0, 0x7B, 0x01, -0x7A, 0x93, 0x79, 0xB6, 0x11, 0xCE, 0x7F, 0x04, 0x80, 0xBA, 0x11, 0xC7, 0x7F, 0xF5, 0x7E, 0x01, -0x12, 0x34, 0xC1, 0xBF, 0x01, 0x06, 0x90, 0x93, 0xAB, 0xE0, 0xA3, 0xF0, 0x11, 0xC7, 0x7F, 0xF6, -0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0x93, 0xAB, 0xE0, 0x90, 0x93, 0xAD, 0xF0, -0x11, 0xC7, 0x7F, 0xF4, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0x93, 0xAB, 0xE0, -0x90, 0x93, 0xAE, 0xF0, 0x11, 0xC7, 0x7F, 0xF3, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, -0x90, 0x93, 0xAB, 0xE0, 0x90, 0x93, 0xAF, 0xF0, 0x11, 0xC7, 0x7F, 0xF2, 0x7E, 0x01, 0x12, 0x34, -0xC1, 0xBF, 0x01, 0x08, 0x90, 0x93, 0xAB, 0xE0, 0x90, 0x93, 0xB0, 0xF0, 0x90, 0x93, 0xAC, 0xE0, -0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x93, 0xB4, 0xF0, 0x90, 0x93, 0xB0, -0xE0, 0x90, 0x93, 0xB5, 0xF0, 0x01, 0x1B, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xAB, 0x22, 0xD3, 0x10, -0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8D, 0xF6, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, -0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x8D, 0xF7, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, -0x7F, 0x00, 0xEF, 0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x29, 0xC0, 0x01, -0x90, 0x8D, 0xF7, 0xE0, 0x12, 0x9F, 0x2A, 0xA8, 0x01, 0xFC, 0x7D, 0x01, 0xD0, 0x01, 0x7E, 0x00, -0x7F, 0x0F, 0x12, 0x06, 0x63, 0x90, 0x8D, 0xF7, 0x91, 0x2B, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, -0x60, 0x05, 0xE4, 0x90, 0x8D, 0xF7, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, -0xC3, 0xC0, 0xD0, 0x90, 0x94, 0xC7, 0xE0, 0xFF, 0x12, 0x9D, 0x27, 0xEF, 0x60, 0x62, 0x90, 0x94, -0xC8, 0xE0, 0xFB, 0xD3, 0x94, 0x00, 0x40, 0x19, 0x90, 0x94, 0xFA, 0x12, 0x08, 0x79, 0x00, 0x00, -0x00, 0x0F, 0xAF, 0x03, 0xE4, 0xFC, 0xFD, 0xFE, 0x71, 0x50, 0x7F, 0x08, 0x7E, 0x0E, 0x12, 0x4D, -0x92, 0x90, 0x94, 0xC7, 0xE0, 0xFF, 0x90, 0x06, 0x33, 0xF0, 0x71, 0x56, 0xF0, 0xE4, 0xFB, 0xFD, -0x31, 0xE3, 0x90, 0x8D, 0xFC, 0xE0, 0xFF, 0x12, 0x9D, 0x52, 0x90, 0x94, 0xC9, 0xE0, 0x90, 0x93, -0xA8, 0xF0, 0x90, 0x94, 0xB4, 0xE0, 0x04, 0xF0, 0xE0, 0xFF, 0x71, 0x92, 0x90, 0x93, 0xA8, 0x12, -0x65, 0x62, 0x90, 0x95, 0x46, 0x12, 0x08, 0x6D, 0x12, 0x9F, 0xD8, 0x12, 0x50, 0x3B, 0x80, 0x3E, -0xE4, 0x90, 0x94, 0xB4, 0xF0, 0x90, 0x94, 0xD0, 0xF0, 0x90, 0x06, 0x32, 0xE0, 0x54, 0xFB, 0xF0, -0x51, 0xDE, 0x90, 0x8D, 0xFF, 0xE0, 0xB4, 0x01, 0x0D, 0x90, 0x94, 0xCC, 0xE0, 0xFD, 0x7F, 0x02, -0x12, 0x53, 0xDC, 0x12, 0x9B, 0x6C, 0x90, 0x93, 0xA9, 0x74, 0x07, 0xF0, 0x90, 0x93, 0xB7, 0xF0, -0x7B, 0x01, 0x7A, 0x93, 0x79, 0xA9, 0x11, 0xCE, 0x7F, 0x04, 0x11, 0x04, 0x71, 0x5E, 0xD0, 0xD0, -0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x66, 0xEF, 0xF0, 0xED, -0x64, 0x01, 0x70, 0x33, 0xEB, 0xB4, 0x01, 0x07, 0xE0, 0x24, 0x02, 0xF5, 0x5A, 0x80, 0x08, 0x90, -0x95, 0x66, 0xE0, 0x24, 0xFE, 0xF5, 0x5A, 0x90, 0x94, 0xE8, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, -0xFF, 0xAF, 0x5A, 0x51, 0x57, 0xE4, 0xFF, 0x51, 0x66, 0x90, 0x94, 0xE8, 0x12, 0x08, 0x79, 0x00, -0x00, 0x00, 0xFF, 0xAF, 0x5A, 0x80, 0x25, 0x90, 0x94, 0xE8, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, -0xFF, 0x90, 0x95, 0x66, 0x12, 0x65, 0x62, 0x51, 0x5B, 0xE4, 0xFF, 0x51, 0x66, 0x90, 0x94, 0xE8, -0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0x90, 0x95, 0x66, 0xE0, 0xFF, 0x51, 0x57, 0x7F, 0x01, -0x51, 0x66, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xFC, 0xFD, 0xFE, 0x90, 0x94, 0xEC, 0x12, 0x08, -0x6D, 0x7D, 0x18, 0x7C, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, 0xE6, -0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x94, 0xE5, 0xEF, 0xF0, 0xA3, 0xA3, 0xE0, 0xFD, 0x12, 0x3E, -0x02, 0x90, 0x94, 0xF0, 0x12, 0x08, 0x6D, 0x90, 0x94, 0xE8, 0x12, 0x43, 0xE5, 0x12, 0x08, 0x3A, -0x90, 0x94, 0xF0, 0x12, 0x4F, 0xF4, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x94, -0xE8, 0x12, 0x43, 0xE5, 0x90, 0x94, 0xEC, 0x12, 0x4F, 0xF4, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, -0xD0, 0x00, 0x12, 0x43, 0xC7, 0x90, 0x94, 0xF4, 0x12, 0x08, 0x6D, 0x90, 0x94, 0xE6, 0xA3, 0xE0, -0xFD, 0xC0, 0x05, 0x90, 0x94, 0xF4, 0x12, 0x43, 0xE5, 0x90, 0xAA, 0x96, 0x12, 0x08, 0x6D, 0x90, -0x94, 0xE5, 0xE0, 0xFF, 0xD0, 0x05, 0x12, 0x3D, 0x09, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8D, -0xFB, 0x91, 0x0B, 0x30, 0xE0, 0x08, 0x12, 0x9F, 0xEF, 0xE4, 0x90, 0x94, 0xCF, 0xF0, 0x90, 0x94, -0xFA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, 0xB5, 0x12, 0x65, 0x62, 0x71, 0x50, -0x7F, 0x50, 0x7E, 0x0C, 0x12, 0x4F, 0x38, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, -0xB6, 0x12, 0x65, 0x62, 0x71, 0x50, 0x12, 0x4D, 0x8E, 0x90, 0x94, 0xCB, 0xE0, 0x90, 0x06, 0x08, -0xF0, 0x90, 0x94, 0xCD, 0xA3, 0xE0, 0x90, 0x06, 0xA0, 0xF0, 0xA3, 0xE4, 0xF0, 0x90, 0x94, 0xB9, -0xE0, 0xFF, 0x60, 0x06, 0xA3, 0xE0, 0xFD, 0x12, 0x4D, 0xF4, 0x90, 0x94, 0xB8, 0xE0, 0xFF, 0x60, -0x0B, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0x71, 0x56, 0xF0, 0x31, 0xE3, 0x22, 0x12, 0x08, 0x5A, -0x90, 0x94, 0xFE, 0x02, 0x08, 0x6D, 0x90, 0x94, 0xBF, 0xE0, 0x90, 0x95, 0x69, 0x22, 0x12, 0x9E, -0xF1, 0x30, 0xE0, 0x25, 0x12, 0x9F, 0x5F, 0x60, 0x0C, 0x12, 0x9F, 0x55, 0x40, 0x07, 0x71, 0x8A, -0x90, 0x91, 0x3F, 0x80, 0x05, 0x71, 0x8A, 0x90, 0x91, 0x37, 0x12, 0x43, 0xF1, 0x12, 0x42, 0x9D, -0x90, 0x95, 0x46, 0x12, 0x08, 0x6D, 0x12, 0x50, 0x34, 0x22, 0xE4, 0x7F, 0xE8, 0x7E, 0x03, 0xFD, -0xFC, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0xB8, 0xEF, 0xF0, 0x90, 0x8D, -0xFD, 0xE0, 0xFF, 0x12, 0x66, 0x4A, 0x74, 0x10, 0x2F, 0xFF, 0x90, 0x93, 0xB8, 0xE0, 0x25, 0xE0, -0x25, 0xE0, 0x2F, 0xFF, 0x71, 0xC4, 0x71, 0xD5, 0x7A, 0x94, 0x79, 0xC7, 0x12, 0x35, 0x26, 0xD0, -0xD0, 0x92, 0xAF, 0x22, 0x24, 0x00, 0xF9, 0xE4, 0x34, 0xFC, 0x75, 0x40, 0x01, 0xF5, 0x41, 0x22, -0x75, 0x40, 0x01, 0xF5, 0x41, 0x89, 0x42, 0x75, 0x43, 0x04, 0x7B, 0x01, 0x22, 0x91, 0x03, 0x2F, -0x71, 0xC6, 0x89, 0x42, 0x75, 0x43, 0x08, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0xF9, 0x02, 0x35, 0x26, -0x91, 0x03, 0x2F, 0x71, 0xC6, 0x89, 0x42, 0x75, 0x43, 0x70, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x61, -0x02, 0x35, 0x26, 0x12, 0x66, 0x4A, 0x7E, 0x00, 0x74, 0x00, 0x22, 0xE0, 0xFF, 0x13, 0x13, 0x54, -0x3F, 0x22, 0x90, 0x93, 0x89, 0x91, 0x0B, 0x30, 0xE0, 0x0E, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x00, -0x12, 0x9F, 0x10, 0x04, 0xF0, 0x02, 0x55, 0xD5, 0x02, 0x57, 0x83, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, -0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8D, 0x5F, 0xE0, 0xFF, 0x90, 0x8D, -0x5E, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x3F, 0x90, 0x8D, -0x5E, 0xE0, 0xFE, 0x75, 0xF0, 0x08, 0x90, 0x8D, 0x0E, 0x12, 0x43, 0xFD, 0xE0, 0xFD, 0xEE, 0x75, -0xF0, 0x08, 0xA4, 0x24, 0x0F, 0xF9, 0x74, 0x8D, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xAF, 0x05, 0x91, -0x92, 0x90, 0x8D, 0x5E, 0x91, 0x2B, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, -0x8D, 0x5E, 0xF0, 0x12, 0x69, 0xFE, 0x90, 0x8D, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, -0xAF, 0x22, 0x90, 0x93, 0xA7, 0x12, 0x9F, 0xA0, 0x90, 0x93, 0xA7, 0xE0, 0xFF, 0x90, 0x06, 0x34, -0xF0, 0xEF, 0x12, 0x44, 0x1B, 0x84, 0xE2, 0x00, 0x84, 0xEB, 0x01, 0x84, 0xF4, 0x02, 0x84, 0xFD, -0x03, 0x85, 0x05, 0x04, 0x85, 0x0D, 0x12, 0x85, 0x15, 0x14, 0x85, 0x1E, 0x20, 0x85, 0x27, 0x21, -0x85, 0x2F, 0x23, 0x85, 0x38, 0x25, 0x85, 0x41, 0x27, 0x85, 0x51, 0x80, 0x85, 0x49, 0x81, 0x85, -0x5A, 0x82, 0x85, 0x63, 0x83, 0x85, 0x6B, 0x84, 0x85, 0x7D, 0x86, 0x85, 0x74, 0x88, 0x00, 0x00, -0x85, 0x85, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0x02, 0x77, 0x89, 0x90, 0x93, 0xA8, 0x12, 0x44, -0x09, 0x02, 0x88, 0x19, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0x02, 0x8D, 0xEA, 0x90, 0x93, 0xA8, -0x12, 0x44, 0x09, 0xA1, 0xA8, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0xC1, 0x33, 0x90, 0x93, 0xA8, -0x12, 0x44, 0x09, 0xA1, 0x95, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0x02, 0x8E, 0x27, 0x90, 0x93, -0xA8, 0x12, 0x44, 0x09, 0x02, 0x74, 0x22, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0xA1, 0xC7, 0x90, -0x93, 0xA8, 0x12, 0x44, 0x09, 0x02, 0x8E, 0x36, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0x02, 0x8E, -0x3E, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0xA1, 0xF0, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0xE1, -0x3E, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0x02, 0x75, 0xD0, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, -0x02, 0x98, 0x87, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0xC1, 0xFD, 0x90, 0x93, 0xA8, 0x12, 0x44, -0x09, 0x02, 0x98, 0x9D, 0x90, 0x93, 0xA8, 0x12, 0x44, 0x09, 0x02, 0x98, 0xEB, 0x90, 0x93, 0xA8, -0x12, 0x44, 0x09, 0xC1, 0x67, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x93, 0xA7, 0xE0, -0x90, 0x01, 0xC2, 0xF0, 0x22, 0x12, 0x06, 0x89, 0xFF, 0x90, 0x8D, 0xFA, 0xF0, 0xBF, 0x01, 0x07, -0x11, 0x4A, 0xE4, 0x90, 0x8D, 0xFA, 0xF0, 0x22, 0xD1, 0x2B, 0x90, 0x93, 0x89, 0xD1, 0x1D, 0x54, -0x04, 0xFF, 0xEE, 0x54, 0xFB, 0x4F, 0xF0, 0x12, 0x06, 0x89, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, -0x75, 0xCA, 0x90, 0x93, 0x8A, 0xF0, 0x22, 0x12, 0x77, 0x7B, 0xFF, 0x30, 0xE0, 0x1D, 0x12, 0x06, -0x89, 0x90, 0x8F, 0x23, 0x12, 0x75, 0xC9, 0x90, 0x8F, 0x24, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0xA3, -0xE0, 0x54, 0x01, 0x12, 0x77, 0x81, 0x90, 0x8F, 0x26, 0xF0, 0x22, 0x12, 0x8D, 0x61, 0xF0, 0x22, -0xD1, 0x2B, 0x90, 0x8F, 0x2A, 0xD1, 0x1D, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F, 0x12, 0x75, -0xC9, 0x90, 0x8F, 0x2B, 0x12, 0x77, 0x7A, 0x90, 0x8F, 0x2C, 0xF0, 0x90, 0x8F, 0x2B, 0xE0, 0x90, -0x8F, 0x2D, 0xF0, 0x90, 0x8F, 0x2A, 0xE0, 0x54, 0x01, 0xFF, 0x02, 0x6D, 0xAF, 0xE0, 0x54, 0xFE, -0x4E, 0xFE, 0xF0, 0xEF, 0x22, 0x90, 0x93, 0xAB, 0x12, 0x44, 0x09, 0x12, 0x06, 0x89, 0xFF, 0x54, -0x01, 0xFE, 0x22, 0x12, 0x77, 0xCB, 0x12, 0x8D, 0x74, 0xD1, 0x25, 0x12, 0x9A, 0x19, 0x4E, 0xF0, -0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x20, 0x12, 0x75, 0xCA, 0x90, 0x93, 0x8E, 0x12, 0x77, 0x7A, 0x90, -0x93, 0x8F, 0xF0, 0x12, 0x06, 0x89, 0x54, 0x04, 0xFF, 0x90, 0x93, 0x8D, 0xE0, 0x54, 0xFB, 0x12, -0x77, 0x81, 0x90, 0x93, 0x90, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x02, -0x09, 0xE0, 0xFD, 0xD1, 0x2B, 0x90, 0x8D, 0xFB, 0xF1, 0xE5, 0xFC, 0xEF, 0x54, 0xFB, 0x4C, 0xFF, -0x90, 0x8D, 0xFB, 0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x12, 0x75, 0xC8, 0xFF, 0xED, -0x2F, 0x90, 0x8D, 0xFC, 0x12, 0x77, 0x7A, 0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x8D, 0xFD, 0xF0, -0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0x20, 0xE0, 0x08, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x0A, -0x90, 0x06, 0x31, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x66, 0xB0, 0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0x30, -0xE0, 0x36, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x06, 0x09, 0xE0, 0x54, 0xFE, 0x12, -0x9D, 0x1F, 0xF0, 0xEF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x09, 0x12, 0x9F, 0xF7, 0x90, 0x94, -0xCF, 0x74, 0x01, 0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x6D, 0xA1, 0x90, 0x95, 0x46, 0x12, 0x08, -0x79, 0x00, 0x00, 0x27, 0x10, 0x12, 0x50, 0x34, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x98, 0xDD, -0x90, 0x93, 0x79, 0x12, 0x75, 0xC9, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x7A, 0x12, 0x77, 0x7A, 0xFF, -0xED, 0x2F, 0x90, 0x93, 0x7B, 0x12, 0x77, 0x82, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x7C, 0x12, 0x77, -0xC4, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x7D, 0x12, 0x77, 0xD1, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x7E, -0xF0, 0x12, 0x74, 0xF8, 0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x93, 0x7F, 0xF0, 0x22, 0xD3, 0x10, -0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xD1, 0x2B, 0x90, 0x8F, 0x2E, 0xF1, 0xE5, 0xFD, 0xEF, 0x54, 0xFB, -0x4D, 0xFF, 0x90, 0x8F, 0x2E, 0x12, 0x9E, 0xAA, 0x54, 0x10, 0xFD, 0xEF, 0x54, 0xEF, 0x12, 0x9F, -0xB0, 0x54, 0x20, 0xFE, 0xEF, 0x54, 0xDF, 0x12, 0x9E, 0xB2, 0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, -0x12, 0x9F, 0xB0, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F, 0x4E, 0x12, 0x77, 0x7A, 0x54, 0x01, 0xFF, -0x90, 0x8F, 0x30, 0xE0, 0x54, 0xFE, 0x4F, 0x12, 0x75, 0xC9, 0x54, 0x01, 0xFF, 0x90, 0x8F, 0x2F, -0xE0, 0x54, 0xFE, 0x4F, 0x12, 0x61, 0x53, 0x12, 0x9F, 0xB8, 0x90, 0x8F, 0x2E, 0xE0, 0xC3, 0x13, -0x54, 0x01, 0xFF, 0x12, 0x98, 0xFB, 0xF1, 0xDE, 0x54, 0x01, 0xFF, 0x12, 0x99, 0x07, 0xF1, 0xDE, -0x13, 0x54, 0x01, 0xFF, 0x12, 0x99, 0x13, 0x90, 0x8F, 0x2E, 0xE0, 0xC4, 0x54, 0x01, 0xFF, 0x12, -0x99, 0x67, 0x90, 0x8F, 0x2E, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x01, 0xFF, 0x12, 0x67, 0xD9, 0x90, -0x8F, 0x2E, 0xE0, 0x54, 0x01, 0xFF, 0x12, 0x6F, 0x87, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8F, -0x2E, 0xE0, 0x13, 0x13, 0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, -0x54, 0xFD, 0x4F, 0xFF, 0xF0, 0x12, 0x06, 0x89, 0xFE, 0x54, 0x04, 0x22, 0x90, 0x95, 0x8B, 0x11, -0x12, 0x90, 0x8D, 0x02, 0xE0, 0xFF, 0x90, 0x95, 0x8B, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x8D, 0x02, -0xF0, 0x22, 0xEF, 0xF0, 0x7F, 0x02, 0x02, 0x48, 0x12, 0x8B, 0x51, 0x8A, 0x52, 0x89, 0x53, 0x12, -0x75, 0xCA, 0xFF, 0xF5, 0x55, 0x12, 0x06, 0x89, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, 0x77, -0x7B, 0xF5, 0x56, 0x80, 0x02, 0x8F, 0x56, 0x85, 0x55, 0x54, 0xE5, 0x54, 0xD3, 0x95, 0x56, 0x50, -0x21, 0xAB, 0x51, 0xAA, 0x52, 0xA9, 0x53, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFF, 0x11, 0x78, 0xEF, -0xF0, 0x11, 0x78, 0xE0, 0xAF, 0x54, 0x70, 0x04, 0x11, 0x8A, 0x80, 0x02, 0x11, 0x84, 0x05, 0x54, -0x80, 0xD8, 0x11, 0x9E, 0xE5, 0x55, 0x70, 0x0F, 0x90, 0x8D, 0xFF, 0xE0, 0x70, 0x09, 0x12, 0x6D, -0x7E, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22, 0x74, 0xFF, 0x25, 0x54, 0xF5, 0x82, 0xE4, 0x34, -0x8D, 0xF5, 0x83, 0x22, 0x11, 0x90, 0x54, 0xFB, 0xF0, 0x22, 0x11, 0x90, 0x44, 0x04, 0xF0, 0x22, -0x8F, 0x57, 0x75, 0xF0, 0x10, 0xEF, 0x90, 0x81, 0x05, 0x12, 0x43, 0xFD, 0xE0, 0x22, 0xE4, 0xFF, -0x11, 0xB7, 0xE4, 0xF0, 0x0F, 0xEF, 0xB4, 0x19, 0xF7, 0xE4, 0x90, 0x8E, 0x97, 0xF0, 0x90, 0x8E, -0x9B, 0xF0, 0x90, 0x8E, 0x95, 0xF0, 0x22, 0x74, 0x9C, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8E, 0xF5, -0x83, 0x22, 0xE4, 0x90, 0x94, 0x59, 0xF0, 0xFD, 0xA3, 0xF0, 0xB1, 0x12, 0xFB, 0xEB, 0x78, 0x02, -0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0x8E, 0xB7, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, -0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x8E, 0xB7, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xC3, 0x9F, -0xEA, 0x9E, 0x40, 0x23, 0xEB, 0x9F, 0xFF, 0x90, 0x8E, 0x99, 0xE0, 0xFE, 0xC3, 0x74, 0x0A, 0x9E, -0x2F, 0xFD, 0xC3, 0x94, 0x19, 0x50, 0x0E, 0x74, 0x9C, 0x2D, 0x11, 0xBA, 0xE0, 0x04, 0xF0, 0x90, -0x8E, 0x97, 0xE0, 0x04, 0xF0, 0x31, 0x7C, 0x90, 0x8E, 0x97, 0xE0, 0xC3, 0x94, 0x64, 0x40, 0x5B, -0xE4, 0x90, 0x94, 0x5A, 0xF0, 0x90, 0x94, 0x59, 0xF0, 0x90, 0x94, 0x59, 0xE0, 0xFF, 0xC3, 0x94, -0x19, 0x50, 0x3A, 0x11, 0xB7, 0x51, 0xF7, 0xF0, 0xE0, 0xD3, 0x94, 0x05, 0x40, 0x27, 0x90, 0x94, -0x59, 0xE0, 0xFF, 0x94, 0x0A, 0x40, 0x0A, 0xEF, 0x24, 0xF6, 0x90, 0x8E, 0x96, 0xF0, 0xE4, 0x80, -0x0E, 0xE4, 0x90, 0x8E, 0x96, 0xF0, 0x90, 0x94, 0x59, 0xE0, 0xFF, 0xC3, 0x74, 0x0A, 0x9F, 0x90, -0x8E, 0x95, 0xF0, 0x80, 0x08, 0x90, 0x94, 0x59, 0xE0, 0x04, 0xF0, 0x80, 0xBC, 0x90, 0x8E, 0x96, -0xE0, 0xFD, 0x7B, 0x08, 0xE4, 0xFF, 0x12, 0x7F, 0xA0, 0x11, 0x9E, 0x22, 0xB1, 0x34, 0x40, 0x20, -0x90, 0x8E, 0x9B, 0xE0, 0x04, 0xF0, 0xE0, 0xFF, 0x94, 0x04, 0x50, 0x14, 0x90, 0x8E, 0x95, 0xEF, -0xF0, 0x25, 0xE0, 0x24, 0x08, 0x90, 0x8E, 0x9A, 0xF0, 0xFB, 0xB1, 0x0A, 0xFD, 0x12, 0x7F, 0xA0, -0x22, 0x7E, 0x00, 0x7F, 0xA3, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x8E, 0x79, 0x80, 0x12, 0x08, 0xAA, -0x51, 0x7D, 0x12, 0x08, 0xAA, 0x90, 0x8E, 0x83, 0x74, 0x02, 0xF0, 0x90, 0x8E, 0x8A, 0x14, 0xF0, -0xA3, 0xF0, 0xA3, 0x74, 0x08, 0x51, 0x4B, 0x74, 0x02, 0x51, 0x3B, 0xE4, 0xFD, 0xFF, 0x12, 0x53, -0xDC, 0x7D, 0x0C, 0x7F, 0x02, 0x12, 0x53, 0xDC, 0x51, 0x90, 0x90, 0x8D, 0x06, 0xE0, 0xFF, 0xB4, -0x01, 0x08, 0x90, 0x8E, 0x8E, 0x74, 0xDD, 0xF0, 0x80, 0x0F, 0xEF, 0x90, 0x8E, 0x8E, 0xB4, 0x03, -0x05, 0x74, 0xD4, 0xF0, 0x80, 0x03, 0x74, 0x40, 0xF0, 0x7F, 0x79, 0x12, 0x4A, 0x84, 0xEF, 0x54, -0x03, 0xFF, 0xBF, 0x02, 0x0F, 0x7F, 0x28, 0x12, 0x4A, 0x84, 0xEF, 0x30, 0xE2, 0x06, 0x90, 0x8E, -0xBB, 0x74, 0x02, 0xF0, 0xB1, 0x61, 0x51, 0x3B, 0x11, 0x9E, 0x7E, 0x00, 0x7F, 0x02, 0x7D, 0x00, -0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x27, 0x12, 0x08, 0xAA, 0x51, 0xEF, 0x90, 0x06, 0x0A, 0xE0, 0x54, -0xF8, 0xF0, 0x12, 0x57, 0xF3, 0xE4, 0x90, 0x8F, 0x29, 0xF0, 0x22, 0xF0, 0x90, 0x8E, 0xBB, 0xE0, -0x24, 0x04, 0x90, 0x8E, 0x99, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x22, 0xF0, 0x90, 0x8E, 0x8F, 0xE4, -0xF0, 0xA3, 0x22, 0x51, 0x8A, 0xB1, 0x40, 0x31, 0xA1, 0x51, 0x78, 0x12, 0x6F, 0xE1, 0xB1, 0x4E, -0xB1, 0x74, 0x90, 0x93, 0x96, 0xE0, 0x54, 0x7F, 0xF0, 0x54, 0xBF, 0xF0, 0x54, 0xDF, 0xF0, 0x54, -0xF0, 0xF0, 0xE4, 0x90, 0x93, 0x98, 0xF0, 0x22, 0x51, 0x7D, 0x02, 0x08, 0xAA, 0x7E, 0x00, 0x7F, -0x04, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x2A, 0x22, 0xE4, 0x90, 0x8D, 0xFF, 0xF0, 0x22, -0x7D, 0x0C, 0x7F, 0x01, 0x02, 0x53, 0xDC, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, -0x93, 0xEF, 0xF0, 0x90, 0x8D, 0x09, 0xE0, 0xFF, 0x90, 0x04, 0x1C, 0xE0, 0x6F, 0x70, 0x3B, 0x90, -0x8E, 0x87, 0xE0, 0x64, 0x0E, 0x70, 0x13, 0x90, 0x95, 0x93, 0xE0, 0x70, 0x2D, 0x90, 0x8E, 0x80, -0xE0, 0x54, 0x7F, 0xF0, 0x51, 0xEF, 0x51, 0x90, 0x80, 0x1D, 0x90, 0x8E, 0x87, 0xE0, 0x64, 0x06, -0x70, 0x18, 0x90, 0x95, 0x93, 0xE0, 0x60, 0x12, 0x90, 0x8E, 0x80, 0xE0, 0x54, 0xBF, 0xF0, 0xB1, -0x28, 0x90, 0x8E, 0x87, 0x74, 0x04, 0xF0, 0x12, 0x57, 0xF3, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, -0x06, 0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x22, 0xE0, 0xFF, 0x90, 0x94, 0x5A, 0xE0, 0x2F, 0x22, 0xE4, -0x90, 0x94, 0x5C, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x20, 0xF0, 0xB1, 0x8E, 0xEF, -0x64, 0x01, 0x70, 0x6A, 0x90, 0x93, 0x84, 0xE0, 0xFF, 0x7B, 0x08, 0x7D, 0x01, 0x12, 0x7A, 0x64, -0x90, 0x94, 0x59, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x94, 0x59, 0x71, 0x87, 0x90, 0x94, 0x5B, -0xEF, 0xF0, 0x90, 0x94, 0x59, 0xB1, 0x1C, 0xE4, 0xFD, 0x71, 0xCD, 0x90, 0x94, 0x5B, 0x51, 0xF7, -0xFF, 0x90, 0x94, 0x59, 0xE0, 0x34, 0x00, 0xCF, 0x24, 0x30, 0xCF, 0x34, 0x00, 0xFE, 0x90, 0x94, -0x5C, 0xF0, 0xA3, 0xEF, 0xF0, 0xB1, 0xBC, 0x71, 0x7F, 0xFD, 0x90, 0x93, 0x84, 0xE0, 0xFB, 0xE4, -0xFF, 0x12, 0x61, 0x65, 0x71, 0x7F, 0xFD, 0x90, 0x93, 0x80, 0xE0, 0xFB, 0x7F, 0x11, 0x12, 0x61, -0x65, 0x12, 0x57, 0xEC, 0x90, 0x90, 0xEF, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x08, 0xD6, 0x22, 0x90, -0x94, 0x5C, 0xE0, 0xFC, 0xA3, 0xE0, 0x22, 0xA3, 0xE0, 0xFE, 0x24, 0x28, 0xF5, 0x82, 0xE4, 0x34, -0xFC, 0xF5, 0x83, 0xE0, 0xFF, 0x74, 0x29, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, -0xFD, 0x74, 0x2C, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, -0x30, 0xE7, 0x04, 0x7C, 0x02, 0x80, 0x02, 0xE4, 0xFC, 0xED, 0x30, 0xE6, 0x08, 0xAF, 0x03, 0x91, -0xCB, 0xAE, 0x07, 0x80, 0x02, 0xE4, 0xFE, 0xEC, 0x24, 0x18, 0x2E, 0xFF, 0x22, 0x90, 0x95, 0x4E, -0xED, 0xF0, 0x90, 0x95, 0x4B, 0x12, 0x44, 0x12, 0xE4, 0x90, 0x95, 0x4F, 0xF0, 0xA3, 0xF0, 0x12, -0x06, 0x89, 0xFF, 0x12, 0x75, 0xCA, 0xFD, 0x12, 0x77, 0xC5, 0xFB, 0x71, 0xAD, 0x90, 0x95, 0x4F, -0xEF, 0xF0, 0x90, 0x95, 0x4B, 0x12, 0x44, 0x09, 0x12, 0x77, 0xC5, 0xFF, 0x91, 0xCB, 0x90, 0x95, -0x50, 0xEF, 0xF0, 0x90, 0x90, 0x02, 0xE0, 0x24, 0xFE, 0x60, 0x14, 0x24, 0xFE, 0x60, 0x10, 0x14, -0x60, 0x07, 0x14, 0x60, 0x04, 0x24, 0x05, 0x70, 0x41, 0x91, 0x5B, 0x91, 0x67, 0x80, 0x0D, 0x91, -0x5B, 0x90, 0x90, 0x02, 0xE0, 0x90, 0x95, 0x20, 0xF0, 0x12, 0x74, 0xFE, 0x90, 0x95, 0x50, 0xE0, -0xFF, 0x90, 0x95, 0x4B, 0x12, 0x44, 0x09, 0x90, 0x95, 0x4F, 0xE0, 0x7C, 0x00, 0x29, 0xF9, 0xEC, -0x3A, 0xFA, 0xC3, 0xE9, 0x9F, 0xF9, 0xEA, 0x94, 0x00, 0xFA, 0x75, 0x40, 0x01, 0x75, 0x41, 0x8F, -0x75, 0x42, 0xF9, 0xA3, 0xE0, 0xF5, 0x43, 0x12, 0x35, 0x26, 0x22, 0x7B, 0x01, 0x7A, 0x8F, 0x79, -0xF9, 0x90, 0x95, 0x4E, 0xE0, 0xFD, 0x22, 0x90, 0x95, 0x3A, 0xED, 0xF0, 0x90, 0x95, 0x37, 0x12, -0x44, 0x12, 0x12, 0x77, 0x83, 0x90, 0x95, 0x3E, 0xF0, 0x90, 0x95, 0x37, 0x12, 0x56, 0xE5, 0x75, -0x43, 0x03, 0x7B, 0x01, 0x7A, 0x95, 0x79, 0x3B, 0x12, 0x35, 0x26, 0x90, 0x95, 0x3A, 0xE0, 0x70, -0x2E, 0xFF, 0x91, 0xC0, 0xE0, 0xB4, 0xFF, 0x06, 0x91, 0xC0, 0xE4, 0xF0, 0x80, 0x07, 0x91, 0xC0, -0xE0, 0x04, 0xF0, 0x80, 0x05, 0x0F, 0xEF, 0xB4, 0x03, 0xE8, 0x75, 0x40, 0x01, 0x75, 0x41, 0x95, -0x75, 0x42, 0x3B, 0x75, 0x43, 0x03, 0x90, 0x95, 0x37, 0x12, 0x44, 0x09, 0x12, 0x35, 0x26, 0x22, -0x74, 0x3B, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x95, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, -0xC0, 0xD0, 0xEF, 0x20, 0xE0, 0x05, 0x90, 0x93, 0x77, 0x80, 0x03, 0x90, 0x93, 0x78, 0xE0, 0x90, -0x90, 0x02, 0xF0, 0x90, 0x90, 0x02, 0xE0, 0x14, 0x60, 0x13, 0x14, 0x60, 0x14, 0x24, 0xFE, 0x60, -0x10, 0x14, 0x60, 0x09, 0x14, 0x60, 0x06, 0x24, 0x06, 0xE4, 0xFE, 0x80, 0x06, 0x7E, 0x04, 0x80, -0x02, 0x7E, 0x08, 0xAF, 0x06, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8E, 0x95, 0xE0, 0xFF, 0xA3, -0xE0, 0x22, 0x90, 0x05, 0x62, 0xE0, 0xFE, 0x90, 0x05, 0x61, 0xE0, 0x22, 0xA3, 0xE0, 0x24, 0x28, -0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x40, 0xF0, 0xE0, -0x44, 0x80, 0xF0, 0x22, 0x90, 0x8F, 0x23, 0xE0, 0xFF, 0x90, 0x8E, 0x8D, 0xE0, 0xD3, 0x9F, 0x22, -0xE4, 0x90, 0x8D, 0xF6, 0xF0, 0xA3, 0xF0, 0x90, 0x8D, 0x5E, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x93, -0x89, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0x7F, 0xF0, 0x54, 0xFB, 0xF0, 0xA3, 0x74, 0x0A, 0x02, 0x59, -0xBE, 0x90, 0x8F, 0x23, 0x74, 0x05, 0xF0, 0xA3, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28, 0xF0, -0xA3, 0x74, 0x05, 0x22, 0x7E, 0x00, 0x7F, 0x08, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x8D, -0x12, 0x08, 0xAA, 0x90, 0x93, 0x8E, 0x74, 0x08, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22, 0xD3, 0x10, -0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1A, 0x90, 0x05, 0x22, 0xE0, 0x54, -0x90, 0x60, 0x07, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE1, -0xE4, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xAD, 0x07, 0x90, 0x90, -0xE7, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x08, 0xD6, 0x90, 0x90, 0xE7, 0xE0, 0xFF, 0xAE, 0x05, 0x74, -0x04, 0x2E, 0x12, 0x67, 0xA7, 0xEF, 0xF0, 0x90, 0x90, 0xE7, 0xA3, 0xE0, 0xFF, 0x74, 0x05, 0x2E, -0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, -0xD0, 0x8B, 0x51, 0x8A, 0x52, 0x89, 0x53, 0x12, 0x06, 0x89, 0xFF, 0x90, 0x8E, 0x7F, 0xF0, 0xBF, -0x01, 0x0D, 0x12, 0x75, 0xCA, 0x64, 0x01, 0x60, 0x19, 0x7D, 0x13, 0x7F, 0x6F, 0x80, 0x10, 0xAB, -0x51, 0xAA, 0x52, 0xA9, 0x53, 0x12, 0x75, 0xCA, 0x64, 0x01, 0x60, 0x06, 0xE4, 0xFD, 0xFF, 0x12, -0x54, 0x51, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x06, 0x89, 0x54, 0x01, 0xFF, 0x90, 0x93, 0x9B, -0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x90, 0x8E, 0x8E, 0xF0, 0x22, 0x12, 0x06, -0x89, 0x90, 0x8F, 0x29, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x5A, -0xEE, 0xF0, 0xA3, 0xEF, 0x12, 0x59, 0xBE, 0x90, 0x95, 0x5A, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82, -0x8E, 0x83, 0xE0, 0x60, 0x21, 0xC3, 0x90, 0x95, 0x5D, 0xE0, 0x94, 0xE8, 0x90, 0x95, 0x5C, 0xE0, -0x94, 0x03, 0x40, 0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x00, 0x80, 0x09, 0x90, -0x95, 0x5C, 0xD1, 0x8D, 0x80, 0xD1, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x75, 0xF0, -0x01, 0x12, 0x08, 0xD6, 0x7F, 0x0A, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x90, 0x01, 0x9A, 0xE0, 0x54, -0xC0, 0x44, 0x0B, 0xF0, 0xD1, 0x94, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xC0, 0x7F, 0x00, 0xB4, 0x40, -0x02, 0x7F, 0x01, 0x22, 0xE4, 0xFC, 0xED, 0x2C, 0x24, 0x00, 0xF1, 0x09, 0xE4, 0xF0, 0x0C, 0xEC, -0xB4, 0x18, 0xF3, 0xF1, 0x06, 0xEF, 0xF0, 0xEE, 0x54, 0x3F, 0xFF, 0x74, 0x01, 0x2D, 0xF5, 0x82, -0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, -0x83, 0xE0, 0x54, 0xF0, 0xF0, 0xF1, 0xC3, 0xE0, 0x44, 0x80, 0xF0, 0x74, 0x0B, 0x2D, 0xF5, 0x82, -0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, -0x34, 0xFB, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x00, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, -0x22, 0x90, 0x01, 0x1F, 0xE0, 0xFE, 0x90, 0x01, 0x1E, 0x12, 0x61, 0x5C, 0x90, 0x93, 0xAB, 0xF0, -0xA3, 0xEF, 0xF0, 0x90, 0x02, 0x87, 0xE0, 0xF9, 0x90, 0x8F, 0x2E, 0xE0, 0x30, 0xE0, 0x7C, 0xEC, -0xC3, 0x99, 0x50, 0x77, 0x90, 0x93, 0xAB, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xF1, 0xD6, 0xAD, 0x07, -0xD1, 0xFA, 0x12, 0x9E, 0xFC, 0x54, 0x3F, 0x90, 0x93, 0xAD, 0xF1, 0xAC, 0xE0, 0x54, 0x03, 0xFB, -0xEF, 0x24, 0x18, 0xFF, 0xE4, 0x33, 0xCF, 0x2B, 0xCF, 0x3A, 0x90, 0x93, 0xAD, 0x8F, 0xF0, 0x12, -0x08, 0xD6, 0x90, 0x93, 0xAD, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x93, 0x78, 0xF1, 0xCE, 0xF0, -0x90, 0x93, 0xAB, 0xEE, 0x8F, 0xF0, 0xF1, 0xDE, 0xFE, 0xA3, 0xE0, 0xFF, 0xD3, 0x90, 0x93, 0xAC, -0xE0, 0x9F, 0x90, 0x93, 0xAB, 0xE0, 0x9E, 0x40, 0x14, 0x90, 0x8D, 0xF9, 0x12, 0x9F, 0x05, 0xFE, -0xC3, 0x90, 0x93, 0xAC, 0xE0, 0x9F, 0xF0, 0x90, 0x93, 0xAB, 0xE0, 0x9E, 0xF0, 0x90, 0x93, 0xAB, -0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x93, 0x6A, 0x0C, 0x80, 0x84, 0x22, 0xF0, 0xA3, 0xEF, 0xF0, -0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54, 0x0F, 0x33, 0x33, 0x33, -0x54, 0xF8, 0xFF, 0x74, 0x03, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x22, 0x90, 0x93, -0xAD, 0xEE, 0xF0, 0xA3, 0xEF, 0x22, 0xEA, 0x90, 0xFD, 0x11, 0xF0, 0xAF, 0x03, 0x22, 0x12, 0x08, -0xD6, 0x90, 0x8D, 0xF8, 0xE0, 0x22, 0x90, 0x95, 0x5E, 0x12, 0x9F, 0xA0, 0x90, 0x95, 0x7C, 0xE0, -0xFE, 0x04, 0xF0, 0x12, 0x90, 0x4B, 0x74, 0x00, 0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, -0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x95, 0x5F, 0x12, 0x56, 0xE5, 0x75, 0x43, 0x02, 0xD0, -0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, 0x90, 0x95, 0x5E, 0xE0, 0x24, 0x02, 0xF9, 0xE4, -0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0xA3, 0x12, 0x44, 0x09, 0xE9, -0x24, 0x02, 0xF9, 0xE4, 0x3A, 0x8B, 0x40, 0xF5, 0x41, 0x89, 0x42, 0x90, 0x95, 0x5F, 0x11, 0x52, -0xF5, 0x43, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x02, 0x35, 0x26, 0x90, 0x00, 0x01, 0xEE, 0x02, -0x06, 0xE1, 0x12, 0x44, 0x09, 0x90, 0x00, 0x0E, 0x02, 0x06, 0xA2, 0xEF, 0x70, 0x04, 0x74, 0xF0, -0x80, 0x16, 0xEF, 0xB4, 0x01, 0x04, 0x74, 0xF4, 0x80, 0x0E, 0xEF, 0xB4, 0x02, 0x04, 0x74, 0xF8, -0x80, 0x06, 0xEF, 0xB4, 0x03, 0x0C, 0x74, 0xFC, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, -0xEB, 0xF0, 0x22, 0x90, 0x95, 0x72, 0x12, 0x44, 0x12, 0xE4, 0xFF, 0x90, 0x95, 0x72, 0x12, 0x44, -0x09, 0x8F, 0x82, 0x75, 0x83, 0x00, 0x12, 0x06, 0xA2, 0xFE, 0x74, 0xF0, 0x2F, 0xF5, 0x82, 0xE4, -0x34, 0x02, 0x11, 0xA8, 0xB4, 0x10, 0xE4, 0x22, 0xF5, 0x83, 0xEE, 0xF0, 0x0F, 0xEF, 0x22, 0xE4, -0xFF, 0x74, 0x18, 0x11, 0xD3, 0x74, 0x3D, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xEE, -0xF0, 0x74, 0x10, 0x11, 0xD3, 0x74, 0x37, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0x11, 0xA8, 0xB4, -0x06, 0xDF, 0x22, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFE, 0x22, 0xE4, 0xFF, -0x74, 0xF9, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x84, 0x2F, 0xF5, -0x82, 0xE4, 0x34, 0x04, 0x11, 0xA8, 0xB4, 0x08, 0xE7, 0x90, 0x90, 0x01, 0xE0, 0x90, 0x04, 0x8C, -0xF0, 0x22, 0x31, 0x27, 0x11, 0xDE, 0x90, 0x01, 0x3F, 0x74, 0x04, 0xF0, 0x90, 0x8D, 0x06, 0xE0, -0xFF, 0xB4, 0x01, 0x07, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xEF, 0xF0, 0xEF, 0xB4, 0x01, 0x07, 0x90, -0xFE, 0x10, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFD, -0x7F, 0x8F, 0x12, 0x49, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0xF1, 0xE0, 0x54, 0xF0, -0xC4, 0x54, 0x0F, 0xFF, 0x22, 0xE4, 0xF5, 0x0D, 0xF5, 0x0E, 0xF5, 0x0F, 0x75, 0x10, 0x80, 0xAD, -0x0D, 0x7F, 0x50, 0x12, 0x49, 0x39, 0xAD, 0x0E, 0x7F, 0x51, 0x12, 0x49, 0x39, 0xAD, 0x0F, 0x7F, -0x52, 0x12, 0x49, 0x39, 0xAD, 0x10, 0x7F, 0x53, 0x02, 0x49, 0x39, 0x12, 0x4F, 0x7B, 0x12, 0x4F, -0x5A, 0x31, 0x77, 0x31, 0x96, 0x80, 0xCE, 0x75, 0x15, 0x10, 0xE4, 0xF5, 0x16, 0x75, 0x17, 0x07, +0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x8E, 0x11, 0x12, +0x9F, 0xD5, 0x30, 0xE0, 0x15, 0xEF, 0x54, 0xBF, 0xF1, 0xEE, 0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, +0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFE, 0xF0, 0x12, 0x74, 0xB2, 0xE4, 0xFF, 0x90, 0x93, 0x2C, 0xE0, +0x30, 0xE0, 0x3D, 0x90, 0x93, 0x31, 0xE0, 0xFD, 0x60, 0x36, 0x12, 0x89, 0xAA, 0x80, 0x05, 0xC3, +0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x04, 0xE0, 0xE0, 0xFB, 0xEF, 0x5B, 0x60, 0x0B, +0xE4, 0x90, 0x93, 0x31, 0xF0, 0x90, 0x93, 0x33, 0x04, 0xF0, 0x22, 0x90, 0x93, 0x2E, 0xE0, 0xD3, +0x9D, 0x50, 0x04, 0x31, 0x6A, 0xF0, 0x22, 0x12, 0x65, 0x55, 0x90, 0x93, 0x31, 0xE0, 0x04, 0xF0, +0x22, 0x90, 0x8E, 0x11, 0x31, 0x18, 0x30, 0xE0, 0x1B, 0xEF, 0x54, 0x7F, 0xF1, 0xEE, 0x30, 0xE1, +0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x8E, 0x15, 0xE0, 0x60, +0x03, 0x12, 0x74, 0xB2, 0x7F, 0x01, 0x80, 0x94, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x13, 0x54, 0x01, +0x22, 0x90, 0x95, 0x2B, 0xEF, 0xF0, 0x90, 0x8D, 0x06, 0xE0, 0x64, 0x02, 0x70, 0x22, 0x90, 0x95, +0x2B, 0xE0, 0xFD, 0x64, 0x01, 0x70, 0x28, 0x12, 0x6F, 0x98, 0x90, 0x8E, 0xC8, 0xE0, 0x31, 0x1A, +0x30, 0xE0, 0x09, 0x90, 0x01, 0x4D, 0xE0, 0x64, 0x80, 0xF0, 0x80, 0x13, 0xAF, 0x05, 0x80, 0x0C, +0x90, 0x06, 0x90, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x95, 0x2B, 0xE0, 0xFF, 0x12, 0x4C, 0x50, 0x31, +0x74, 0xF0, 0x90, 0x8E, 0xC4, 0xE0, 0x54, 0xBF, 0xF0, 0x22, 0x90, 0x01, 0xC7, 0x74, 0x10, 0xF0, +0x7F, 0x01, 0x31, 0x21, 0x90, 0x93, 0x2C, 0xE0, 0x54, 0xFE, 0x22, 0xF1, 0x3E, 0x12, 0x06, 0x89, +0xFF, 0x54, 0x7F, 0x90, 0x8E, 0x15, 0xF0, 0xEF, 0x31, 0x1A, 0xA3, 0x12, 0x77, 0xC2, 0xFF, 0x54, +0xF0, 0xC4, 0x54, 0x0F, 0xFE, 0x90, 0x8E, 0x13, 0xE0, 0x54, 0xF0, 0x4E, 0xB1, 0xF7, 0x54, 0x01, +0x25, 0xE0, 0xFE, 0x90, 0x8E, 0x11, 0xE0, 0x54, 0xFD, 0x4E, 0xF0, 0xEF, 0x54, 0x0F, 0xC4, 0x54, +0xF0, 0xFF, 0x12, 0x77, 0xF5, 0xB1, 0xB2, 0x90, 0x8E, 0x14, 0xF0, 0x91, 0x93, 0x30, 0xE0, 0x4D, +0xC3, 0x13, 0x54, 0x07, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x8E, 0x28, 0x50, 0x04, 0xEF, 0xF0, 0x80, +0x25, 0x74, 0x03, 0xF0, 0x51, 0x25, 0xE9, 0x24, 0x06, 0xF1, 0xC5, 0xFF, 0x74, 0x03, 0x24, 0xFD, +0xFE, 0xEF, 0xC4, 0x54, 0x0F, 0xFD, 0xEF, 0x54, 0x0F, 0xFF, 0xED, 0x2E, 0x54, 0x0F, 0xFE, 0xC4, +0x54, 0xF0, 0x4F, 0x12, 0x06, 0xCF, 0x51, 0x25, 0x91, 0x93, 0xC4, 0x54, 0x0F, 0xFF, 0xC3, 0x94, +0x04, 0x90, 0x8E, 0x1D, 0x50, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x02, 0xEF, 0xF0, 0x51, 0x25, 0xB1, +0x70, 0xFD, 0x7F, 0x02, 0x12, 0x4E, 0xB5, 0x90, 0x94, 0x6F, 0xE0, 0x60, 0x03, 0x12, 0x4E, 0xA9, +0x51, 0x25, 0x02, 0x77, 0xC9, 0x90, 0x93, 0x4A, 0x02, 0x44, 0x09, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0xF1, 0x3E, 0x12, 0x06, 0x89, 0x20, 0xE0, 0x05, 0x12, 0x8B, 0x24, 0x41, 0xEE, 0x90, +0x8F, 0x98, 0x74, 0x05, 0xF0, 0xF1, 0x53, 0x90, 0x8E, 0xC7, 0x51, 0xF3, 0xF1, 0xD4, 0xFF, 0x90, +0x8E, 0xC7, 0x12, 0x9E, 0xF1, 0x71, 0x01, 0xF1, 0xDC, 0x90, 0x8E, 0xC7, 0x12, 0xA0, 0xE9, 0x71, +0x01, 0xF1, 0xE5, 0x90, 0x8E, 0xC7, 0x12, 0xA0, 0xDF, 0x12, 0x77, 0xC2, 0x54, 0x80, 0xFF, 0x90, +0x8E, 0xC8, 0xE0, 0x54, 0x7F, 0x4F, 0xF0, 0x12, 0x06, 0x89, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, +0x07, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x04, 0xF0, 0x51, 0x25, 0x12, 0x06, 0x89, 0x13, 0x13, 0x13, +0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x8D, 0x06, 0xE0, +0xB4, 0x02, 0x09, 0x90, 0x8E, 0xC8, 0xE0, 0x31, 0x1A, 0x20, 0xE0, 0x34, 0x12, 0x77, 0xC3, 0x54, +0x7F, 0xFF, 0x90, 0x8E, 0xC8, 0xE0, 0x54, 0x80, 0xB1, 0xB2, 0x90, 0x8E, 0xC9, 0xB1, 0xF7, 0xFF, +0x54, 0x01, 0xFE, 0x90, 0x8E, 0xCA, 0xF1, 0xCC, 0x54, 0xFE, 0xFF, 0xEE, 0x54, 0x01, 0x4F, 0xF0, +0x12, 0x4C, 0xF0, 0x13, 0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x12, 0x4A, 0x6A, +0x90, 0x8D, 0x06, 0xE0, 0xB4, 0x01, 0x07, 0x90, 0xFE, 0x10, 0xE0, 0x44, 0x04, 0xF0, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, +0x4F, 0xFF, 0xF0, 0x12, 0x06, 0x89, 0xFE, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, +0x59, 0x90, 0x8E, 0xC4, 0x51, 0xF3, 0xF1, 0xD4, 0xFF, 0x90, 0x8E, 0xC4, 0x12, 0x9E, 0xF1, 0x71, +0x01, 0xF1, 0xDC, 0x90, 0x8E, 0xC4, 0x12, 0xA0, 0xE9, 0x71, 0x01, 0xF1, 0xE5, 0x90, 0x8E, 0xC4, +0x12, 0xA0, 0xDF, 0xB1, 0xB3, 0x54, 0x01, 0xFF, 0x90, 0x8E, 0xC6, 0xE0, 0x54, 0xFE, 0x4F, 0x12, +0x77, 0xC2, 0x54, 0x01, 0xFF, 0x90, 0x8E, 0xC5, 0xE0, 0x54, 0xFE, 0x4F, 0x12, 0x84, 0x9A, 0x12, +0x87, 0xE4, 0x90, 0x8E, 0xC4, 0xE0, 0xC3, 0x13, 0x54, 0x01, 0xFF, 0x12, 0x99, 0xC9, 0xF1, 0x44, +0x54, 0x01, 0xFF, 0x12, 0x99, 0x35, 0xF1, 0x44, 0x13, 0x54, 0x01, 0xFF, 0x12, 0x99, 0xD5, 0x90, +0x8E, 0xC4, 0xE0, 0xC4, 0x54, 0x01, 0xFF, 0x12, 0x9A, 0x2C, 0x90, 0x8E, 0xC4, 0xE0, 0xC4, 0x13, +0x13, 0x54, 0x01, 0xFF, 0x12, 0x9A, 0x3A, 0x90, 0x8E, 0xC4, 0xE0, 0x54, 0x01, 0xFF, 0x12, 0x86, +0x70, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x93, 0x47, 0x12, 0x44, 0x12, 0x90, 0x93, 0x46, 0xEF, +0xF0, 0x12, 0x44, 0x1B, 0x7B, 0xE1, 0x00, 0x7B, 0xE9, 0x01, 0x7B, 0xF2, 0x02, 0x7B, 0xFB, 0x03, +0x7C, 0x04, 0x04, 0x7C, 0x0C, 0x12, 0x7C, 0x15, 0x14, 0x7C, 0x1E, 0x20, 0x7C, 0x26, 0x21, 0x7C, +0x2E, 0x23, 0x7C, 0x37, 0x25, 0x7C, 0x40, 0x27, 0x7C, 0x50, 0x80, 0x7C, 0x48, 0x81, 0x7C, 0x58, +0x82, 0x7C, 0x61, 0x83, 0x7C, 0x69, 0x84, 0x7C, 0x7A, 0x86, 0x7C, 0x71, 0x88, 0x00, 0x00, 0x7C, +0x83, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0xA1, 0x76, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x02, +0x73, 0xE7, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x02, 0x87, 0xEC, 0x90, 0x93, 0x47, 0x12, 0x44, +0x09, 0x02, 0x90, 0x85, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0xE1, 0x07, 0x90, 0x93, 0x47, 0x12, +0x44, 0x09, 0x02, 0x88, 0x29, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x02, 0x88, 0x3D, 0x90, 0x93, +0x47, 0x12, 0x44, 0x09, 0x21, 0x7B, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0xE1, 0x61, 0x90, 0x93, +0x47, 0x12, 0x44, 0x09, 0x02, 0x88, 0x4C, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x02, 0x88, 0x54, +0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0xE1, 0x99, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x61, 0x08, +0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x41, 0x2B, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x02, 0x99, +0xA3, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0xA1, 0xBA, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0xA1, +0xFE, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, 0x02, 0x99, 0xB9, 0x90, 0x93, 0x47, 0x12, 0x44, 0x09, +0x02, 0x9E, 0x4F, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x93, 0x46, 0xE0, 0x90, 0x01, +0xC2, 0xF0, 0x22, 0x90, 0x00, 0x06, 0x02, 0x06, 0xA2, 0x90, 0x94, 0xBB, 0x12, 0x44, 0x12, 0x12, +0x06, 0x89, 0x90, 0x94, 0xC0, 0x12, 0x77, 0xC2, 0x90, 0x94, 0xC1, 0xB1, 0x6F, 0x90, 0x94, 0xC2, +0xF1, 0x37, 0x90, 0x94, 0xC3, 0xF0, 0x91, 0x93, 0x90, 0x94, 0xC4, 0xF0, 0x90, 0x00, 0x07, 0x12, +0x06, 0xA2, 0x90, 0x94, 0xC5, 0xB1, 0xF7, 0x90, 0x94, 0xC8, 0xF0, 0xED, 0x70, 0x19, 0xFF, 0xB1, +0x64, 0xE0, 0xB4, 0xFF, 0x06, 0xB1, 0x64, 0xE4, 0xF0, 0x80, 0x07, 0xB1, 0x64, 0xE0, 0x04, 0xF0, +0x80, 0x05, 0x0F, 0xEF, 0xB4, 0x06, 0xE8, 0x90, 0x94, 0xBF, 0xE0, 0xFF, 0xB4, 0x04, 0x14, 0xA3, +0xE0, 0xFE, 0xB1, 0x5E, 0xEE, 0xF1, 0x4B, 0xFE, 0xB1, 0x5E, 0x12, 0x8A, 0x53, 0x90, 0x00, 0x02, +0xE4, 0x80, 0x20, 0xEF, 0xB4, 0x02, 0x1F, 0x90, 0x94, 0xC1, 0xB1, 0x5C, 0xEF, 0xF1, 0x4B, 0x44, +0x20, 0x54, 0x7F, 0xB1, 0x5D, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x06, 0xE1, 0x90, 0x94, 0xC0, 0xE0, +0x90, 0x00, 0x02, 0x12, 0x06, 0xE1, 0xB1, 0x5E, 0xE9, 0x24, 0x03, 0xF1, 0xC5, 0x44, 0x20, 0x12, +0x06, 0xCF, 0x90, 0x94, 0xC2, 0xB1, 0x5C, 0x90, 0x00, 0x04, 0xEF, 0x12, 0x06, 0xE1, 0x90, 0x94, +0xC3, 0xE0, 0x90, 0x00, 0x05, 0x12, 0x06, 0xE1, 0x90, 0x94, 0xC4, 0xE0, 0x90, 0x00, 0x06, 0x12, +0x06, 0xE1, 0x90, 0x94, 0xC5, 0xE0, 0x90, 0x00, 0x07, 0x02, 0x06, 0xE1, 0xE0, 0xFF, 0x90, 0x94, +0xBB, 0x02, 0x44, 0x09, 0x74, 0xC0, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0xF0, +0x90, 0x00, 0x04, 0x02, 0x06, 0xA2, 0x90, 0x02, 0x09, 0xE0, 0xF5, 0x51, 0x12, 0x06, 0x89, 0x25, +0x51, 0x90, 0x8D, 0x07, 0x12, 0x77, 0xC2, 0x25, 0x51, 0x90, 0x8D, 0x08, 0xB1, 0xB3, 0x25, 0x51, +0x90, 0x8D, 0x09, 0xB1, 0xF7, 0x25, 0x51, 0x90, 0x8D, 0x0A, 0xB1, 0x6F, 0x25, 0x51, 0x90, 0x8D, +0x0B, 0xF1, 0x37, 0x25, 0x51, 0x90, 0x8D, 0x0C, 0xF0, 0x91, 0x93, 0x25, 0x51, 0x90, 0x8D, 0x0D, +0xF0, 0x22, 0x4F, 0xF0, 0x90, 0x00, 0x02, 0x02, 0x06, 0xA2, 0x12, 0xA0, 0x62, 0x90, 0x93, 0x18, +0x12, 0x77, 0xC2, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x19, 0xB1, 0xB3, 0xFF, 0xED, 0x2F, 0x90, 0x93, +0x1A, 0xB1, 0xF7, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x1B, 0xB1, 0x6F, 0xFF, 0xED, 0x2F, 0x90, 0x93, +0x1C, 0xF1, 0x37, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x1D, 0xF0, 0x91, 0x93, 0xFF, 0xAE, 0x05, 0xED, +0x2F, 0x90, 0x93, 0x1E, 0xF0, 0x22, 0x4F, 0xF0, 0x90, 0x00, 0x03, 0x02, 0x06, 0xA2, 0x12, 0xA0, +0x62, 0x90, 0x93, 0x1F, 0x12, 0x77, 0xC2, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x20, 0xB1, 0xB3, 0xFF, +0xED, 0x2F, 0x90, 0x93, 0x21, 0xB1, 0xF7, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x22, 0xB1, 0x6F, 0xFF, +0xED, 0x2F, 0x90, 0x93, 0x23, 0xF1, 0x37, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x24, 0xF0, 0x91, 0x93, +0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x93, 0x25, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x90, 0x06, 0x74, +0x12, 0x77, 0xC2, 0x90, 0x06, 0x75, 0xB1, 0xB3, 0x90, 0x06, 0x76, 0xB1, 0xF7, 0x90, 0x06, 0x77, +0xF0, 0x90, 0x06, 0x70, 0xEF, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x04, 0xF0, 0xA3, 0x74, 0x80, 0xF0, +0x7F, 0x01, 0x7E, 0x00, 0x02, 0x3E, 0x50, 0x90, 0x93, 0xA8, 0xEF, 0xF0, 0xA3, 0x12, 0x44, 0x12, +0x90, 0x93, 0xA9, 0x12, 0x56, 0x7A, 0xD1, 0xE1, 0x24, 0x02, 0xD1, 0xF6, 0x24, 0x04, 0xD1, 0xD8, +0x24, 0x03, 0xD1, 0xF6, 0x24, 0x08, 0xD1, 0xD8, 0x24, 0x04, 0xD1, 0xF6, 0x24, 0x0C, 0xD1, 0xD8, +0x24, 0x05, 0xFF, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xAC, 0xD1, 0x3A, 0x90, 0x93, 0xA8, 0xE0, 0xFE, +0x44, 0x10, 0x90, 0x93, 0xAC, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, +0xEE, 0x75, 0xF0, 0x08, 0xA4, 0xFF, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xAC, 0xD1, 0x3A, 0x90, 0x93, +0xAC, 0x74, 0xFF, 0x12, 0x4D, 0xB3, 0xD1, 0xED, 0x04, 0xFF, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xAC, +0xD1, 0x3A, 0x90, 0x06, 0x72, 0xE4, 0xF0, 0x22, 0xF9, 0xE4, 0x3A, 0x8B, 0x40, 0xF5, 0x41, 0x89, +0x42, 0x75, 0x43, 0x04, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xAC, 0x12, 0x35, 0x26, 0x90, 0x93, 0xA8, +0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x22, 0xFF, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xAC, 0xD1, 0x3A, 0x90, +0x93, 0xA9, 0x12, 0x44, 0x09, 0xE9, 0x22, 0xF1, 0x3E, 0x12, 0x89, 0xD2, 0xF1, 0x53, 0x31, 0x74, +0x4E, 0xF0, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x1E, 0x12, 0x77, 0xC3, 0x90, 0x93, 0x2D, 0xB1, 0xB3, +0x90, 0x93, 0x2E, 0xF0, 0x12, 0x06, 0x89, 0x54, 0x04, 0xFF, 0x90, 0x93, 0x2C, 0xE0, 0x54, 0xFB, +0xB1, 0xF6, 0x90, 0x93, 0x2F, 0xF0, 0x22, 0xF0, 0x90, 0x00, 0x05, 0x02, 0x06, 0xA2, 0x90, 0x93, +0x4A, 0x02, 0x44, 0x12, 0x90, 0x8E, 0xC4, 0xE0, 0x13, 0x13, 0x22, 0x12, 0x06, 0xCF, 0x90, 0x94, +0xC1, 0xE0, 0x22, 0x90, 0x93, 0x4A, 0x12, 0x44, 0x09, 0x12, 0x06, 0x89, 0xFF, 0x54, 0x01, 0xFE, +0x22, 0xB1, 0xB4, 0xFF, 0x30, 0xE0, 0x1C, 0x12, 0x06, 0x89, 0x90, 0x8E, 0xB9, 0x12, 0x77, 0xC2, +0x90, 0x8E, 0xBA, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0xA3, 0xE0, 0x54, 0x01, 0xB1, 0xF6, 0x90, 0x8E, +0xBC, 0xF0, 0x22, 0x90, 0x8E, 0xB9, 0x74, 0x05, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0xA3, 0xE0, 0x54, +0x01, 0x44, 0x1E, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0x22, 0xF1, 0x59, 0x90, 0x8E, 0xC0, 0xF1, 0xCC, +0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F, 0x12, 0x77, 0xC2, 0x90, 0x8E, 0xC1, 0xB1, 0xB3, 0x90, +0x8E, 0xC2, 0xF0, 0x90, 0x8E, 0xC1, 0xE0, 0x90, 0x8E, 0xC3, 0xF0, 0x90, 0x8E, 0xC0, 0xE0, 0x54, +0x01, 0xFF, 0x02, 0x76, 0x34, 0xF9, 0xE4, 0x3A, 0xFA, 0x02, 0x06, 0x89, 0xE0, 0x54, 0xFE, 0x4E, +0xFE, 0xF0, 0xEF, 0x22, 0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0x22, 0x54, 0x10, 0xFD, 0xEF, +0x54, 0xEF, 0x4D, 0xFF, 0x22, 0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0x4D, 0xFF, 0x22, 0xF0, 0x90, +0x04, 0xE0, 0xE0, 0x90, 0x8E, 0x12, 0x22, 0x32, 0x90, 0x95, 0x27, 0xEF, 0xF0, 0x7F, 0x02, 0x12, +0x48, 0x12, 0x90, 0x8D, 0x01, 0xE0, 0xFF, 0x90, 0x95, 0x27, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x8D, +0x01, 0xF0, 0x22, 0x90, 0x93, 0x55, 0x74, 0x12, 0xF0, 0x90, 0x93, 0x63, 0x74, 0x05, 0xF0, 0x90, +0x93, 0x57, 0xEF, 0x71, 0x9D, 0x90, 0x93, 0x53, 0xE0, 0x90, 0x93, 0x5A, 0xF0, 0x90, 0x93, 0x54, +0xE0, 0x90, 0x93, 0x5B, 0xF0, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x55, 0x11, 0xC5, 0x7F, 0x04, 0x80, +0xB7, 0x11, 0xBE, 0x7F, 0xF5, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x06, 0x90, 0x93, 0x4A, +0xE0, 0xA3, 0xF0, 0x11, 0xBE, 0x7F, 0xF6, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, +0x93, 0x4A, 0xE0, 0x90, 0x93, 0x4C, 0xF0, 0x11, 0xBE, 0x7F, 0xF4, 0x7E, 0x01, 0x12, 0x34, 0xC1, +0xBF, 0x01, 0x08, 0x90, 0x93, 0x4A, 0xE0, 0x90, 0x93, 0x4D, 0xF0, 0x11, 0xBE, 0x7F, 0xF3, 0x7E, +0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0x93, 0x4A, 0xE0, 0x90, 0x93, 0x4E, 0xF0, 0x11, +0xBE, 0x7F, 0xF2, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x08, 0x90, 0x93, 0x4A, 0xE0, 0x90, +0x93, 0x4F, 0xF0, 0x90, 0x93, 0x4B, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, +0x90, 0x93, 0x53, 0xF0, 0x90, 0x93, 0x4F, 0xE0, 0x90, 0x93, 0x54, 0xF0, 0x01, 0x13, 0x7B, 0x01, +0x7A, 0x93, 0x79, 0x4A, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8D, 0xF6, 0xE0, +0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x8D, 0xF7, 0xE0, +0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, +0x44, 0x02, 0xF0, 0x80, 0x28, 0xC0, 0x01, 0x90, 0x8D, 0xF7, 0xE0, 0x71, 0xCD, 0xA8, 0x01, 0xFC, +0x7D, 0x01, 0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x06, 0x63, 0x90, 0x8D, 0xF7, 0x71, 0x7E, +0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x8D, 0xF7, 0xF0, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, 0x66, 0xE0, 0xFF, 0x12, 0x9F, +0x9E, 0xEF, 0x70, 0x02, 0x21, 0xDB, 0x90, 0x94, 0x67, 0xE0, 0xFB, 0xD3, 0x94, 0x00, 0x40, 0x1A, +0x90, 0x94, 0x99, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x0F, 0xAF, 0x03, 0xE4, 0xFC, 0xFD, 0xFE, +0x12, 0x5F, 0xA9, 0x7F, 0x08, 0x7E, 0x0E, 0x12, 0x5E, 0xCE, 0x90, 0x94, 0x66, 0xE0, 0xFF, 0x90, +0x06, 0x33, 0xF0, 0x71, 0xA5, 0xE4, 0xFB, 0xFD, 0x51, 0x4A, 0x90, 0x94, 0x69, 0xE0, 0x60, 0x07, +0x90, 0x8D, 0xFC, 0xE0, 0xFF, 0x51, 0x20, 0x71, 0x85, 0x30, 0xE0, 0x39, 0x90, 0x90, 0xCB, 0xE0, +0x60, 0x33, 0xE4, 0x90, 0x93, 0x48, 0xF0, 0x90, 0x90, 0xCB, 0xE0, 0xFF, 0x90, 0x93, 0x48, 0xE0, +0xC3, 0x9F, 0x50, 0x21, 0x7F, 0x03, 0x7E, 0x00, 0x12, 0x3D, 0xC2, 0x90, 0x93, 0x48, 0xE0, 0x24, +0x0A, 0x71, 0x8D, 0xE0, 0xFF, 0x51, 0x20, 0x90, 0x01, 0xA6, 0xE0, 0x04, 0xF0, 0x90, 0x93, 0x48, +0xE0, 0x04, 0xF0, 0x80, 0xD2, 0x90, 0x94, 0x68, 0xE0, 0x90, 0x93, 0x47, 0xF0, 0x90, 0x94, 0x53, +0xE0, 0x04, 0xF0, 0xE0, 0xFF, 0x12, 0x9F, 0x6D, 0x90, 0x93, 0x47, 0x12, 0x5D, 0x80, 0x90, 0x94, +0xE5, 0x12, 0x08, 0x6D, 0x71, 0x95, 0x12, 0x50, 0x4C, 0x80, 0x40, 0xE4, 0x90, 0x94, 0x53, 0xF0, +0x90, 0x94, 0x6F, 0xF0, 0x90, 0x06, 0x32, 0xE0, 0x54, 0xFB, 0xF0, 0x12, 0x5F, 0x3A, 0xE4, 0xFF, +0x12, 0x73, 0x2E, 0xBF, 0x01, 0x0C, 0x90, 0x94, 0x6B, 0xE0, 0xFD, 0x7F, 0x02, 0x12, 0x4E, 0xB5, +0x71, 0xAE, 0x90, 0x93, 0x49, 0x74, 0x07, 0xF0, 0x90, 0x93, 0x57, 0xF0, 0x7B, 0x01, 0x7A, 0x93, +0x79, 0x49, 0x11, 0xC5, 0x7F, 0x04, 0x12, 0x7F, 0xF8, 0x71, 0x49, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x58, 0xEF, 0xF0, 0x12, 0x8F, 0x6B, 0xBF, +0x01, 0x13, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x93, 0x58, 0x12, 0x64, 0x32, 0x90, +0x93, 0x59, 0x12, 0x57, 0xFC, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x95, 0x05, 0xEF, 0xF0, 0xED, 0x64, 0x01, 0x70, 0x33, 0xEB, 0xB4, 0x01, 0x07, 0xE0, +0x24, 0x02, 0xF5, 0x5A, 0x80, 0x08, 0x90, 0x95, 0x05, 0xE0, 0x24, 0xFE, 0xF5, 0x5A, 0x90, 0x94, +0x87, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0x5A, 0x71, 0x34, 0xE4, 0xFF, 0x51, 0xBE, +0x90, 0x94, 0x87, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0x5A, 0x80, 0x25, 0x90, 0x94, +0x87, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0x90, 0x95, 0x05, 0x12, 0x5D, 0x80, 0x71, 0x38, +0xE4, 0xFF, 0x51, 0xBE, 0x90, 0x94, 0x87, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0xFF, 0x90, 0x95, +0x05, 0xE0, 0xFF, 0x71, 0x34, 0x7F, 0x01, 0x51, 0xBE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, 0x85, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x94, 0x84, +0xEF, 0xF0, 0xA3, 0xA3, 0xE0, 0xFD, 0x12, 0x3E, 0x02, 0x90, 0x94, 0x8F, 0x12, 0x08, 0x6D, 0x90, +0x94, 0x87, 0x12, 0x43, 0xE5, 0x12, 0x08, 0x3A, 0x90, 0x94, 0x8F, 0x71, 0x43, 0xC0, 0x04, 0xC0, +0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x94, 0x87, 0x12, 0x43, 0xE5, 0x90, 0x94, 0x8B, 0x71, 0x43, +0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x43, 0xC7, 0x90, 0x94, 0x93, 0x12, 0x08, +0x6D, 0x90, 0x94, 0x85, 0xA3, 0xE0, 0xFD, 0xC0, 0x05, 0x90, 0x94, 0x93, 0x12, 0x43, 0xE5, 0x90, +0xAA, 0x96, 0x12, 0x08, 0x6D, 0x90, 0x94, 0x84, 0xE0, 0xFF, 0xD0, 0x05, 0x12, 0x3D, 0x09, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xFC, 0xFD, 0xFE, 0x90, 0x94, 0x8B, 0x12, 0x08, 0x6D, 0x7D, 0x18, +0x7C, 0x00, 0x22, 0x12, 0x43, 0xF1, 0x02, 0x43, 0xBA, 0x90, 0x8D, 0xFB, 0x12, 0x77, 0x4B, 0x30, +0xE0, 0x23, 0x71, 0xC2, 0x60, 0x0B, 0x71, 0xB8, 0x40, 0x07, 0x71, 0x76, 0x90, 0x90, 0xD6, 0x80, +0x05, 0x71, 0x76, 0x90, 0x90, 0xCE, 0x12, 0x43, 0xF1, 0x12, 0x42, 0x9D, 0x90, 0x94, 0xE5, 0x12, +0x08, 0x6D, 0x12, 0x50, 0x45, 0x22, 0xE4, 0x7F, 0xE8, 0x7E, 0x03, 0xFD, 0xFC, 0x22, 0xE0, 0x04, +0xF0, 0xE0, 0x7F, 0x00, 0x22, 0x90, 0x8E, 0xC4, 0xE0, 0xC4, 0x54, 0x0F, 0x22, 0xF5, 0x82, 0xE4, +0x34, 0x91, 0xF5, 0x83, 0x22, 0xE4, 0x90, 0x94, 0xE9, 0xF0, 0x7F, 0x04, 0x22, 0xF0, 0xA3, 0xED, +0xF0, 0xA3, 0xEB, 0xF0, 0x22, 0x90, 0x94, 0x5E, 0xE0, 0x90, 0x95, 0x08, 0xF0, 0x22, 0x12, 0x4F, +0xE9, 0x7D, 0x04, 0x7F, 0x01, 0x02, 0x4E, 0xB5, 0x90, 0x93, 0x12, 0x12, 0x43, 0xF1, 0xD3, 0x02, +0x43, 0xD4, 0x90, 0x90, 0xD2, 0x12, 0x43, 0xE5, 0xEC, 0x4D, 0x4E, 0x4F, 0x22, 0x75, 0xF0, 0x0F, +0xA4, 0x24, 0x60, 0xF9, 0x74, 0x8D, 0x35, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0xE4, 0xFF, 0x90, 0x8D, 0xF7, 0xE0, 0xFE, 0x90, 0x8D, 0xF6, 0xE0, 0xFD, 0xB5, 0x06, 0x04, 0x7E, +0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x64, 0x01, 0x60, 0x3F, 0xED, 0x71, 0xCD, 0xFA, 0x7B, 0x01, +0x91, 0x3E, 0x7F, 0x01, 0xEF, 0x60, 0x32, 0x90, 0x8D, 0xF6, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x0A, +0x02, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x8D, 0xF6, 0xF0, 0x90, 0x8D, 0xF7, +0xE0, 0xFF, 0x90, 0x8D, 0xF6, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, +0x70, 0x07, 0x90, 0x8D, 0x01, 0xE0, 0x44, 0x04, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x95, 0x01, 0x12, 0x44, 0x12, 0x7F, 0x96, 0x7E, 0x02, 0x91, +0xAC, 0xEF, 0x60, 0x41, 0x91, 0x9B, 0xFE, 0x12, 0xA1, 0x40, 0x90, 0x95, 0x04, 0xEF, 0xF0, 0xEE, +0xFF, 0x90, 0xFD, 0x11, 0xF0, 0x90, 0x95, 0x04, 0xE0, 0xFD, 0x90, 0x02, 0x94, 0xF0, 0xA3, 0xEF, +0xF0, 0x90, 0x95, 0x01, 0x12, 0x8A, 0x5A, 0x24, 0x02, 0xFF, 0xE4, 0x33, 0xFE, 0x91, 0xF1, 0x90, +0x95, 0x04, 0xE0, 0x24, 0x18, 0xFF, 0x90, 0x95, 0x01, 0x12, 0x44, 0x09, 0x12, 0x89, 0xEC, 0x90, +0x02, 0x96, 0x74, 0x01, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90, 0x01, 0x17, 0xE0, 0xFE, +0x90, 0x01, 0x16, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF, 0xEC, 0x3E, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x94, 0xF9, 0x12, 0x91, 0x98, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x94, 0xF9, +0x12, 0xA1, 0x17, 0xE0, 0x60, 0x24, 0xC3, 0x90, 0x94, 0xFC, 0xE0, 0x94, 0xE8, 0x90, 0x94, 0xFB, +0xE0, 0x94, 0x03, 0x40, 0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x00, 0x80, 0x0C, +0x90, 0x94, 0xFB, 0x12, 0x61, 0x77, 0xF1, 0xDD, 0x80, 0xD3, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xE4, 0xFC, 0xED, 0x2C, 0x24, 0x00, 0xB1, 0x46, 0xE4, 0xF0, 0x0C, 0xEC, 0xB4, 0x18, 0xF3, +0xB1, 0x43, 0xEF, 0xF0, 0xEE, 0x54, 0x3F, 0xFF, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, +0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54, +0xF0, 0xF0, 0xD1, 0x18, 0xE0, 0x44, 0x80, 0xF0, 0x74, 0x0B, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, +0xF5, 0x83, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, +0x83, 0xE0, 0xFE, 0x74, 0x00, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x22, 0x12, 0xA1, +0x0E, 0x91, 0xA3, 0x90, 0x93, 0x4A, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x02, 0x87, 0xE0, 0xF9, 0x90, +0x8E, 0xC4, 0xE0, 0x30, 0xE0, 0x73, 0xEC, 0xC3, 0x99, 0x50, 0x6E, 0x90, 0x93, 0x4A, 0xE0, 0xFA, +0xA3, 0xE0, 0xFB, 0x12, 0xA1, 0x60, 0xAD, 0x07, 0xB1, 0x37, 0x12, 0xA0, 0x35, 0x54, 0x3F, 0x90, +0x93, 0x4C, 0xD1, 0x01, 0xE0, 0x54, 0x03, 0xFB, 0xEF, 0x24, 0x18, 0xFF, 0xE4, 0x33, 0xCF, 0x2B, +0xCF, 0x3A, 0x90, 0x93, 0x4C, 0x8F, 0xF0, 0x12, 0x08, 0xD6, 0x90, 0x93, 0x4C, 0xB1, 0xDA, 0x12, +0xA1, 0x05, 0x90, 0x93, 0x4A, 0xEE, 0x8F, 0xF0, 0x12, 0xA1, 0x90, 0xFE, 0xA3, 0xE0, 0xFF, 0xD3, +0x90, 0x93, 0x4B, 0xE0, 0x9F, 0x90, 0x93, 0x4A, 0xE0, 0x9E, 0x40, 0x14, 0x90, 0x8D, 0xF9, 0x12, +0xA0, 0x57, 0xFE, 0xC3, 0x90, 0x93, 0x4B, 0xE0, 0x9F, 0xF0, 0x90, 0x93, 0x4A, 0xE0, 0x9E, 0xF0, +0x90, 0x93, 0x4A, 0x12, 0x90, 0xA6, 0x0C, 0x80, 0x8D, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x7D, +0x07, 0xEF, 0x5D, 0xC3, 0x60, 0x0A, 0xB1, 0xF4, 0x24, 0x08, 0xFF, 0xE4, 0x3E, 0xFE, 0x80, 0x03, +0xB1, 0xF4, 0xFF, 0x22, 0x74, 0xFF, 0x9D, 0xFD, 0x74, 0xFF, 0x94, 0x00, 0x5E, 0xFE, 0xED, 0x5F, +0x22, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, +0x54, 0x0F, 0x33, 0x33, 0x33, 0x54, 0xF8, 0xFF, 0x74, 0x03, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, +0xF5, 0x83, 0x22, 0x12, 0x90, 0xEE, 0xAD, 0x07, 0x90, 0x01, 0xC4, 0x74, 0x23, 0xF0, 0x74, 0x86, +0xA3, 0xF0, 0xED, 0x64, 0x01, 0x60, 0x1E, 0x12, 0x6F, 0x98, 0xED, 0xB4, 0x02, 0x08, 0x90, 0x01, +0xC7, 0x74, 0x40, 0xF0, 0x80, 0x0A, 0xED, 0xB4, 0x04, 0x06, 0x90, 0x01, 0xC7, 0x74, 0x41, 0xF0, +0x7F, 0x01, 0x02, 0x79, 0x21, 0xB1, 0x4E, 0x90, 0x02, 0x87, 0xE0, 0x70, 0xF8, 0x90, 0x06, 0x90, +0xE0, 0x44, 0x02, 0xF0, 0x74, 0x23, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x86, 0xA3, 0xF0, 0x22, +0xEF, 0x60, 0x37, 0x90, 0x93, 0x18, 0xE0, 0xFF, 0x60, 0x03, 0x12, 0x99, 0x0A, 0x90, 0x01, 0xC7, +0xE4, 0x91, 0x9A, 0xF1, 0xE4, 0x90, 0x06, 0x09, 0xE0, 0x54, 0xFE, 0xF0, 0x7D, 0x35, 0x12, 0x4B, +0x1C, 0x12, 0x9E, 0xE0, 0xD1, 0x23, 0xF1, 0xA6, 0x12, 0x4F, 0xE7, 0x12, 0x8A, 0xD1, 0x90, 0x01, +0x34, 0x74, 0x08, 0xF0, 0xFD, 0xE4, 0xFF, 0x02, 0x75, 0x25, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x76, +0x27, 0x90, 0x06, 0x90, 0xE0, 0x54, 0xF0, 0xF0, 0x12, 0xA1, 0x48, 0x12, 0x8B, 0x24, 0xF1, 0xD7, +0x12, 0x9E, 0x3E, 0x7A, 0x8E, 0x79, 0xC4, 0x12, 0x08, 0xAA, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x20, +0xF0, 0x12, 0x8B, 0x49, 0x12, 0x4E, 0x87, 0x90, 0x8D, 0x06, 0xE0, 0xFF, 0x64, 0x02, 0x70, 0x2A, +0xF1, 0x9F, 0x30, 0xE0, 0x02, 0x7E, 0x01, 0x90, 0x8E, 0xE3, 0xF1, 0x9D, 0x30, 0xE1, 0x02, 0x7E, +0x01, 0x90, 0x8E, 0xE1, 0xF1, 0x9D, 0x30, 0xE2, 0x02, 0x7E, 0x01, 0x90, 0x8E, 0xE2, 0xEE, 0xF0, +0x90, 0xFD, 0x80, 0xE0, 0x90, 0x02, 0xFB, 0xF0, 0x80, 0x4A, 0xEF, 0x64, 0x01, 0x70, 0x1D, 0xF1, +0x96, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0x8E, 0xE3, 0xF1, 0x94, 0x30, 0xE1, 0x02, 0x7F, 0x01, +0x90, 0x8E, 0xE1, 0xF1, 0x94, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0x80, 0x23, 0x90, 0x8D, 0x06, 0xE0, +0x64, 0x03, 0x70, 0x20, 0xF1, 0x8D, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0x8E, 0xE3, 0xF1, 0x8B, +0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, 0x8E, 0xE1, 0xF1, 0x8B, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0x90, +0x8E, 0xE2, 0xEF, 0xF0, 0x90, 0x8E, 0xC4, 0xE0, 0x54, 0xEF, 0xF0, 0xE4, 0x90, 0x90, 0xCA, 0xF0, +0xA3, 0xF0, 0x90, 0x90, 0xD2, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xD6, 0x12, +0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xCE, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, +0x90, 0x93, 0x12, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x22, 0xEF, 0xF0, 0x90, 0xFD, 0x78, +0xE0, 0x7F, 0x00, 0x22, 0xEF, 0xF0, 0x90, 0xFD, 0x70, 0xE0, 0x7F, 0x00, 0x22, 0xEE, 0xF0, 0x90, +0xFD, 0x80, 0xE0, 0x7E, 0x00, 0x22, 0xF1, 0xDC, 0x71, 0x85, 0x30, 0xE0, 0x18, 0x90, 0x8D, 0xFB, +0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x20, 0xE0, 0x0D, 0x90, 0x94, 0xE5, 0x12, 0x08, 0x79, 0x00, 0x00, +0x00, 0x14, 0x12, 0x50, 0x45, 0x22, 0x90, 0x8E, 0xC4, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, +0x05, 0x12, 0x90, 0x4C, 0xF1, 0x54, 0x22, 0x12, 0x9F, 0xC9, 0x80, 0xEA, 0x22, 0x7F, 0x0A, 0x7E, +0x00, 0x02, 0x3E, 0x50, 0x90, 0x8D, 0xF8, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x8B, 0x51, 0x8A, 0x52, 0x89, 0x53, 0x12, 0x06, 0x89, 0xFF, 0x90, 0x8E, 0x10, +0xF0, 0xBF, 0x01, 0x0D, 0x12, 0x77, 0xC3, 0x64, 0x01, 0x60, 0x19, 0x7D, 0x13, 0x7F, 0x6F, 0x80, +0x10, 0xAB, 0x51, 0xAA, 0x52, 0xA9, 0x53, 0x12, 0x77, 0xC3, 0x64, 0x01, 0x60, 0x06, 0xE4, 0xFD, +0xFF, 0x12, 0x53, 0xD9, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x06, 0x89, 0xFF, 0x90, 0x8D, 0xFA, +0xF0, 0xBF, 0x01, 0x08, 0x12, 0x80, 0x41, 0xE4, 0x90, 0x8D, 0xFA, 0xF0, 0x22, 0x12, 0x06, 0x89, +0x54, 0x01, 0xFF, 0x90, 0x93, 0x3A, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x90, +0x8E, 0x20, 0xF0, 0x22, 0x12, 0x06, 0x89, 0x90, 0x8E, 0xBF, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x8D, 0x5F, 0xE0, 0xFF, 0x90, 0x8D, 0x5E, 0xE0, 0xB5, 0x07, 0x04, 0x7F, +0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x41, 0x90, 0x8D, 0x5E, 0xE0, 0xFE, 0x75, 0xF0, 0x08, +0x90, 0x8D, 0x0E, 0x12, 0x43, 0xFD, 0xE0, 0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x0F, 0xF9, +0x74, 0x8D, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xAF, 0x05, 0x12, 0x7B, 0x96, 0x90, 0x8D, 0x5E, 0x12, +0x83, 0x7E, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x8D, 0x5E, 0xF0, 0x12, +0x71, 0xED, 0x90, 0x8D, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x90, +0x8D, 0xF6, 0xF0, 0xA3, 0xF0, 0x90, 0x8D, 0x5E, 0xF0, 0xA3, 0xF0, 0x22, 0x11, 0xF9, 0x11, 0xBE, +0x12, 0x4F, 0x1F, 0x31, 0x9C, 0x12, 0x86, 0xC0, 0x31, 0xBF, 0x31, 0xD2, 0x90, 0x93, 0x35, 0xE0, +0x54, 0x7F, 0xF0, 0x54, 0xBF, 0xF0, 0x54, 0xDF, 0xF0, 0x54, 0xF0, 0xF0, 0xE4, 0x90, 0x93, 0x37, +0xF0, 0x90, 0x93, 0x35, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0xE4, 0xFD, 0xFF, 0x31, 0xA1, 0xFE, 0xEF, +0x54, 0x07, 0xFF, 0xED, 0x70, 0x12, 0x31, 0x3C, 0xC0, 0x83, 0xC0, 0x82, 0x31, 0x34, 0x80, 0x02, +0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5E, 0x80, 0x0F, 0x31, 0x3C, 0xC0, 0x83, 0xC0, 0x82, 0x31, 0x34, +0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x31, 0x47, 0x90, 0x8E, +0x0F, 0xEF, 0xF0, 0x22, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x22, 0x74, 0xFF, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x8D, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7D, 0x10, +0xED, 0x14, 0xF9, 0x24, 0xFF, 0x31, 0x3F, 0xE0, 0x60, 0x39, 0x7C, 0x08, 0xEC, 0x14, 0x90, 0x95, +0x28, 0xF0, 0x74, 0xFF, 0x29, 0x31, 0x3F, 0xE0, 0xFB, 0x7A, 0x00, 0x90, 0x95, 0x28, 0x31, 0xA8, +0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5A, 0xFE, 0xEF, 0x5B, 0x4E, +0x60, 0x0F, 0xE9, 0x75, 0xF0, 0x08, 0xA4, 0xFF, 0x90, 0x95, 0x28, 0xE0, 0x2F, 0x04, 0xFF, 0x80, +0x06, 0xDC, 0xC9, 0xDD, 0xBB, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x31, 0xB2, 0x02, 0x08, +0xAA, 0xEF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22, 0xE0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, +0x08, 0x22, 0x7E, 0x00, 0x7F, 0x04, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x8E, 0x79, 0xC0, 0x22, 0x90, +0x93, 0x28, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0x7F, 0xF0, 0x54, 0xFB, 0xF0, 0xA3, 0x74, 0x0A, 0x02, +0x67, 0xE6, 0x7E, 0x00, 0x7F, 0x08, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x2C, 0x12, 0x08, +0xAA, 0x90, 0x93, 0x2D, 0x74, 0x08, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22, 0x90, 0x94, 0xFD, 0xEF, +0xF0, 0xA3, 0x12, 0x44, 0x12, 0x90, 0x95, 0x1B, 0xE0, 0xFE, 0x04, 0xF0, 0x51, 0x53, 0x74, 0x00, +0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x94, +0xFE, 0x12, 0x56, 0x7A, 0x75, 0x43, 0x02, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x35, 0x26, +0x90, 0x94, 0xFD, 0xE0, 0x24, 0x02, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, +0x02, 0xC0, 0x01, 0xA3, 0x12, 0x44, 0x09, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0x8B, 0x40, 0xF5, +0x41, 0x89, 0x42, 0x90, 0x94, 0xFE, 0x51, 0x5A, 0xF5, 0x43, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, +0x02, 0x35, 0x26, 0x90, 0x00, 0x01, 0xEE, 0x02, 0x06, 0xE1, 0x12, 0x44, 0x09, 0x90, 0x00, 0x0E, +0x02, 0x06, 0xA2, 0x51, 0x69, 0x54, 0xFB, 0xF0, 0x22, 0x8F, 0x57, 0x75, 0xF0, 0x10, 0xEF, 0x90, +0x81, 0x05, 0x12, 0x43, 0xFD, 0xE0, 0x22, 0x51, 0x69, 0x44, 0x04, 0xF0, 0x22, 0xEF, 0x70, 0x04, +0x74, 0xF0, 0x80, 0x16, 0xEF, 0xB4, 0x01, 0x04, 0x74, 0xF4, 0x80, 0x0E, 0xEF, 0xB4, 0x02, 0x04, +0x74, 0xF8, 0x80, 0x06, 0xEF, 0xB4, 0x03, 0x0C, 0x74, 0xFC, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x02, +0xF5, 0x83, 0xEB, 0xF0, 0x22, 0x90, 0x95, 0x11, 0x12, 0x44, 0x12, 0xE4, 0xFF, 0x90, 0x95, 0x11, +0x12, 0x44, 0x09, 0x8F, 0x82, 0x75, 0x83, 0x00, 0x12, 0x06, 0xA2, 0xFE, 0x74, 0xF0, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x02, 0x51, 0xCA, 0xB4, 0x10, 0xE4, 0x22, 0xF5, 0x83, 0xEE, 0xF0, 0x0F, 0xEF, +0x22, 0xE4, 0xFF, 0x74, 0x18, 0x51, 0xF5, 0x74, 0xD4, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8E, 0xF5, +0x83, 0xEE, 0xF0, 0x74, 0x10, 0x51, 0xF5, 0x74, 0xCE, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8E, 0x51, +0xCA, 0xB4, 0x06, 0xDF, 0x22, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFE, 0x22, +0xE4, 0xFF, 0x74, 0x90, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x84, +0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0x51, 0xCA, 0xB4, 0x08, 0xE7, 0x90, 0x8F, 0x98, 0xE0, 0x90, +0x04, 0x8C, 0xF0, 0x22, 0x71, 0x49, 0x71, 0x00, 0x90, 0x01, 0x3F, 0x74, 0x04, 0xF0, 0x90, 0x8D, +0x06, 0xE0, 0xFF, 0xB4, 0x01, 0x07, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xEF, 0xF0, 0xEF, 0xB4, 0x01, +0x07, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0xE4, 0xFD, 0x7F, 0x8F, 0x12, 0x49, 0x39, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0xF1, 0xE0, +0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF, 0x22, 0x75, 0x15, 0x10, 0xE4, 0xF5, 0x16, 0x75, 0x17, 0x07, 0x75, 0x18, 0x02, 0x90, 0x01, 0x30, 0xE5, 0x15, 0xF0, 0xA3, 0xE5, 0x16, 0xF0, 0xA3, 0xE5, 0x17, 0xF0, 0xA3, 0xE5, 0x18, 0xF0, 0x22, 0x75, 0x1D, 0x07, 0x75, 0x1E, 0x01, 0x75, 0x1F, 0x03, 0x75, 0x20, 0x62, 0x90, 0x01, 0x38, 0xE5, 0x1D, 0xF0, 0xA3, 0xE5, 0x1E, 0xF0, 0xA3, 0xE5, 0x1F, 0xF0, 0xA3, 0xE5, 0x20, 0xF0, 0x22, 0x90, 0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01, 0xC7, 0xE4, -0xF0, 0x22, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22, 0x7D, 0x02, 0x90, 0x01, 0xC4, 0x74, 0xC9, -0xF0, 0x74, 0x91, 0xA3, 0xF0, 0x90, 0x93, 0x88, 0xE0, 0xFF, 0xED, 0xC3, 0x9F, 0x50, 0x10, 0xED, -0x25, 0xE0, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x03, 0x7F, 0x00, 0x22, 0x0D, 0x80, 0xE6, 0x7F, -0x01, 0x22, 0xE4, 0x90, 0x8D, 0x01, 0x12, 0x4F, 0x9F, 0xA3, 0xF0, 0x22, 0x90, 0x01, 0xE4, 0x74, -0x1D, 0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x34, 0xE0, 0x55, 0x15, 0xF5, 0x19, 0xA3, 0xE0, -0x55, 0x16, 0xF5, 0x1A, 0xA3, 0xE0, 0x55, 0x17, 0xF5, 0x1B, 0xA3, 0xE0, 0x55, 0x18, 0xF5, 0x1C, -0x90, 0x01, 0x34, 0xE5, 0x19, 0xF0, 0xA3, 0xE5, 0x1A, 0xF0, 0xA3, 0xE5, 0x1B, 0xF0, 0xA3, 0xE5, -0x1C, 0xF0, 0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x1D, 0xF5, 0x21, 0xA3, 0xE0, 0x55, 0x1E, 0xF5, -0x22, 0xA3, 0xE0, 0x55, 0x1F, 0xF5, 0x23, 0xA3, 0xE0, 0x55, 0x20, 0xF5, 0x24, 0x90, 0x01, 0x3C, -0xE5, 0x21, 0xF0, 0xA3, 0xE5, 0x22, 0xF0, 0xA3, 0xE5, 0x23, 0xF0, 0xA3, 0xE5, 0x24, 0xF0, 0x53, -0x91, 0xDF, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90, 0x94, 0x59, 0xF0, 0xE0, 0xFF, 0x30, 0xE0, 0x07, -0x90, 0x01, 0xCF, 0xE0, 0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE5, 0x23, 0x90, 0x01, 0xCF, 0xE0, 0x54, -0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0xE4, 0xF5, 0xA8, 0xF5, 0xE8, 0x12, 0x4F, 0x7B, -0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x49, 0x39, 0x80, 0xFE, 0x22, 0x90, -0x8E, 0x84, 0xE0, 0x60, 0x03, 0x12, 0x57, 0x68, 0x22, 0x7F, 0x80, 0x02, 0x69, 0xEF, 0xE4, 0x90, -0x94, 0x5F, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x7F, 0x83, 0x12, 0x4A, 0x84, 0x90, 0x94, 0x5F, 0xEF, -0xF0, 0x7F, 0x83, 0x12, 0x4A, 0x84, 0xAE, 0x07, 0x90, 0x94, 0x5F, 0xE0, 0xFF, 0xB5, 0x06, 0x01, -0x22, 0xC3, 0x90, 0x94, 0x61, 0xE0, 0x94, 0x64, 0x90, 0x94, 0x60, 0xE0, 0x94, 0x00, 0x40, 0x0D, -0x90, 0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x94, 0x5F, 0xE0, 0xFF, 0x22, 0x90, 0x94, 0x60, -0xE4, 0x75, 0xF0, 0x01, 0x12, 0x08, 0xD6, 0x80, 0xBE, 0x90, 0x01, 0xC4, 0x74, 0xF9, 0xF0, 0x74, -0x92, 0xA3, 0xF0, 0x7F, 0x90, 0x12, 0x4A, 0x84, 0xEF, 0x20, 0xE0, 0xF7, 0x74, 0xF9, 0x04, 0x90, -0x01, 0xC4, 0xF0, 0x74, 0x92, 0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, -0xFF, 0xEF, 0x12, 0x51, 0x4A, 0xE4, 0xF0, 0x0F, 0xEF, 0xB4, 0x08, 0xF5, 0xD0, 0xD0, 0x92, 0xAF, -0x22, 0x90, 0x01, 0x53, 0xE4, 0xF0, 0xFF, 0xEF, 0x12, 0x51, 0x4A, 0xE4, 0xF0, 0x0F, 0xEF, 0xB4, -0x08, 0xF5, 0x22, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x9C, 0x7F, 0xFB, 0x7E, 0x01, 0x12, 0x34, 0xC1, -0xBF, 0x01, 0x16, 0x90, 0x93, 0x9C, 0xE0, 0x54, 0x30, 0xFF, 0xBF, 0x20, 0x07, 0x90, 0x93, 0x95, -0x74, 0x01, 0xF0, 0x22, 0xE4, 0x90, 0x93, 0x95, 0xF0, 0x22, 0x90, 0x02, 0x84, 0xEF, 0xF0, 0xEE, -0xA3, 0xF0, 0xA3, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x7D, 0x07, 0xEF, 0x5D, 0xC3, 0x60, 0x0A, 0x71, -0x8D, 0x24, 0x08, 0xFF, 0xE4, 0x3E, 0xFE, 0x80, 0x03, 0x71, 0x8D, 0xFF, 0x22, 0x74, 0xFF, 0x9D, -0xFD, 0x74, 0xFF, 0x94, 0x00, 0x5E, 0xFE, 0xED, 0x5F, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE2, -0x03, 0x7F, 0x04, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x7F, 0x01, 0x20, 0xE1, 0x02, 0x7F, 0x02, 0x22, -0x71, 0x9A, 0xAD, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xB0, 0xF0, 0x74, 0x93, 0xA3, 0xF0, 0xED, 0x64, -0x01, 0x60, 0x1E, 0x12, 0x5F, 0xD8, 0xED, 0xB4, 0x02, 0x08, 0x90, 0x01, 0xC7, 0x74, 0x40, 0xF0, -0x80, 0x0A, 0xED, 0xB4, 0x04, 0x06, 0x90, 0x01, 0xC7, 0x74, 0x41, 0xF0, 0x7F, 0x01, 0x02, 0x73, -0xCF, 0x12, 0x8F, 0x11, 0x90, 0x02, 0x87, 0xE0, 0x70, 0xF7, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x02, -0xF0, 0x74, 0xB0, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x93, 0xA3, 0xF0, 0x22, 0x90, 0x8F, 0x36, -0xE0, 0xFF, 0x20, 0xE0, 0x07, 0x90, 0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x14, 0xEF, 0x44, 0x01, 0x90, -0x8F, 0x36, 0xF0, 0x90, 0x8F, 0x31, 0xE0, 0xC4, 0x54, 0x0F, 0x20, 0xE0, 0x03, 0x7F, 0x00, 0x22, -0x7F, 0x01, 0x22, 0xEF, 0x90, 0x01, 0xC7, 0xB4, 0xA0, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x03, 0x74, -0x08, 0xF0, 0x02, 0x5F, 0xD8, 0x12, 0xA0, 0x3F, 0xF0, 0xE4, 0x90, 0x93, 0xBF, 0xF0, 0x90, 0x93, -0xBF, 0xE0, 0xFD, 0xC3, 0x94, 0x06, 0x50, 0x28, 0x90, 0x93, 0xB8, 0xE0, 0x24, 0x04, 0xFF, 0x90, -0x93, 0xB7, 0xE0, 0x34, 0x00, 0xFE, 0x12, 0x5C, 0xFE, 0x90, 0x93, 0xBF, 0xE0, 0x24, 0xB9, 0xF5, -0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x93, 0xBF, 0xE0, 0x04, 0xF0, 0x80, 0xCE, -0x78, 0x37, 0x7C, 0x8F, 0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xB9, 0x91, 0x86, 0xEF, 0x7F, -0x00, 0x70, 0x02, 0x7F, 0x01, 0x22, 0x7E, 0x00, 0x7F, 0x06, 0x02, 0x45, 0xC7, 0xF1, 0xE1, 0x78, -0xB0, 0x7C, 0x93, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x56, 0xF1, 0xBD, 0x78, 0xB6, 0x7C, -0x93, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x5C, 0xF1, 0xC4, 0x78, 0xBA, 0x7C, 0x93, 0x7D, -0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x60, 0xF1, 0xC4, 0xE4, 0x90, 0x93, 0xBF, 0xF0, 0xB1, 0xDA, -0xCF, 0x24, 0x06, 0xCF, 0x12, 0x5F, 0x1B, 0xEF, 0x64, 0x08, 0x60, 0x02, 0xA1, 0xC2, 0xB1, 0xDA, -0xCF, 0x24, 0x07, 0xCF, 0x12, 0x5F, 0x1B, 0xEF, 0x64, 0x06, 0x60, 0x02, 0xA1, 0xC2, 0x90, 0x93, -0xBF, 0x04, 0xF0, 0xE4, 0x90, 0x93, 0xBE, 0xF0, 0xB1, 0xC8, 0x94, 0x06, 0x50, 0x1D, 0x90, 0x93, -0xA8, 0xE0, 0x24, 0x0A, 0xFD, 0x90, 0x93, 0xA7, 0xE0, 0x12, 0x5C, 0xF1, 0x90, 0x93, 0xBE, 0xE0, -0x24, 0xAA, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xB1, 0xCF, 0x80, 0xDD, 0xF1, 0xCB, 0x7B, 0x01, 0x7A, -0x8F, 0x79, 0x3D, 0x91, 0x86, 0xEF, 0x60, 0x02, 0xA1, 0xC2, 0x90, 0x93, 0xBE, 0xF0, 0xB1, 0xC8, -0x94, 0x04, 0x50, 0x1B, 0xF1, 0xA1, 0x2D, 0xFD, 0xB1, 0xE5, 0xCD, 0x24, 0x20, 0x12, 0x5C, 0xF0, -0x90, 0x93, 0xBE, 0xE0, 0x24, 0xBA, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xB1, 0xCF, 0x80, 0xDF, 0x78, -0xBA, 0x7C, 0x93, 0x12, 0x9E, 0xE2, 0xEF, 0x70, 0x70, 0x90, 0x06, 0x30, 0xE0, 0x44, 0x01, 0x54, -0xDF, 0xF0, 0x90, 0x8F, 0x30, 0xE0, 0x30, 0xE0, 0x0A, 0x90, 0x01, 0xC7, 0x74, 0x09, 0x12, 0x5F, -0xD7, 0x80, 0x5F, 0xE4, 0x90, 0x93, 0xBE, 0xF0, 0xB1, 0xC8, 0x94, 0x06, 0x50, 0x12, 0x12, 0x5C, -0xDC, 0x90, 0x93, 0xBE, 0xE0, 0x24, 0xB0, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xB1, 0xCF, 0x80, 0xE8, -0xE4, 0x90, 0x93, 0xBE, 0xF0, 0xB1, 0xC8, 0x94, 0x04, 0x50, 0x1B, 0xF1, 0xA1, 0x2D, 0xFD, 0xB1, -0xE5, 0xCD, 0x24, 0x16, 0x12, 0x5C, 0xF0, 0x90, 0x93, 0xBE, 0xE0, 0x24, 0xB6, 0xF5, 0x82, 0xE4, -0x34, 0x93, 0xB1, 0xCF, 0x80, 0xDF, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xB0, 0x12, 0x9F, 0x10, 0xF0, -0x7A, 0x93, 0x79, 0xB6, 0x12, 0x55, 0xD5, 0x80, 0x09, 0x90, 0x06, 0x30, 0xE0, 0x44, 0x21, 0x54, -0xEF, 0xF0, 0x90, 0x93, 0xBF, 0xE0, 0xFF, 0x22, 0x90, 0x93, 0xBE, 0xE0, 0xFF, 0xC3, 0x22, 0xF5, -0x83, 0xEF, 0xF0, 0x90, 0x93, 0xBE, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x93, 0xA9, 0xE0, 0xFF, 0x90, -0x93, 0xA8, 0xE0, 0x2F, 0xFF, 0x90, 0x93, 0xA7, 0xE0, 0x34, 0x00, 0x22, 0xF1, 0xE1, 0xF1, 0xCB, -0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x6A, 0xF1, 0xBD, 0x78, 0xB0, 0x7C, 0x93, 0x7D, 0x01, 0x7B, 0xFF, -0x7A, 0x40, 0x79, 0x70, 0xF1, 0xD2, 0x78, 0xC0, 0x7C, 0x93, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, -0x79, 0x80, 0xF1, 0xD2, 0xE4, 0x90, 0x93, 0xD3, 0x12, 0x5D, 0xA9, 0xA3, 0xE0, 0xFD, 0xF1, 0xED, -0xEF, 0x64, 0x01, 0x60, 0x02, 0xE1, 0x9B, 0xB1, 0xDA, 0xCF, 0x24, 0x0E, 0xCF, 0x12, 0x5F, 0x1B, -0xEF, 0x64, 0x3A, 0x60, 0x02, 0xE1, 0x9B, 0xB1, 0xDA, 0xCF, 0x24, 0x30, 0xCF, 0x12, 0x5F, 0x1B, -0xEF, 0x64, 0x87, 0x60, 0x02, 0xE1, 0x9B, 0x90, 0x93, 0xD3, 0x04, 0xF0, 0xE4, 0x90, 0x93, 0xD0, -0xF0, 0xF1, 0xAB, 0x94, 0x10, 0x50, 0x1B, 0xF1, 0xA1, 0x2D, 0xFD, 0xB1, 0xE5, 0xCD, 0x24, 0x38, -0x12, 0x5C, 0xF0, 0x90, 0x93, 0xD0, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF1, 0xB2, -0x80, 0xDF, 0xE4, 0x90, 0x93, 0xD1, 0xF0, 0x90, 0x93, 0xD1, 0xE0, 0xFF, 0xC3, 0x94, 0x02, 0x40, -0x02, 0xE1, 0x9B, 0x75, 0xF0, 0x38, 0xEF, 0xF1, 0xD9, 0x20, 0xE0, 0x02, 0xE1, 0x9B, 0xE4, 0x90, -0x93, 0xD2, 0xF0, 0x90, 0x93, 0xD1, 0xE0, 0xFF, 0x75, 0xF0, 0x38, 0x90, 0x8F, 0x62, 0x12, 0x43, -0xFD, 0xE0, 0xFE, 0x90, 0x93, 0xD2, 0xE0, 0xC3, 0x9E, 0x40, 0x02, 0xE1, 0x93, 0xEF, 0x75, 0xF0, -0x38, 0xA4, 0x24, 0x79, 0xF9, 0x74, 0x8F, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xE0, 0x75, 0xF0, 0x10, -0xA4, 0x29, 0xF9, 0xEA, 0x35, 0xF0, 0xFA, 0x78, 0xC0, 0x7C, 0x93, 0x12, 0x9F, 0x80, 0x60, 0x02, -0xE1, 0x84, 0x90, 0x06, 0x33, 0xE0, 0x44, 0x01, 0x54, 0xFB, 0xF0, 0xE4, 0x90, 0x93, 0xD0, 0xF0, -0xF1, 0xAB, 0x94, 0x06, 0x50, 0x1B, 0xF1, 0xA1, 0x2D, 0xFD, 0xB1, 0xE5, 0xCD, 0x24, 0x4A, 0x12, -0x5C, 0xF0, 0x90, 0x93, 0xD0, 0xE0, 0x24, 0xAA, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF1, 0xB2, 0x80, -0xDF, 0xE4, 0x90, 0x93, 0xD0, 0xF0, 0xF1, 0xAB, 0x94, 0x10, 0x50, 0x12, 0x12, 0x5C, 0xDC, 0x90, -0x93, 0xD0, 0xE0, 0x24, 0xB0, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF1, 0xB2, 0x80, 0xE8, 0x90, 0x93, -0xD1, 0xE0, 0xFF, 0x75, 0xF0, 0x38, 0xF1, 0xD9, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x1A, 0xEF, 0x75, -0xF0, 0x38, 0xA4, 0x24, 0x69, 0xF9, 0x74, 0x8F, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x78, 0xB0, 0x7C, -0x93, 0x12, 0x9F, 0x80, 0x70, 0x45, 0x80, 0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xAA, 0x90, 0x93, -0xD7, 0x12, 0x44, 0x12, 0x7A, 0x93, 0x79, 0xC0, 0x90, 0x93, 0xDA, 0x12, 0x44, 0x12, 0x90, 0x93, -0xD1, 0xE0, 0x75, 0xF0, 0x38, 0xA4, 0x24, 0x63, 0xF9, 0x74, 0x8F, 0x35, 0xF0, 0xFA, 0x90, 0x93, -0xDD, 0x12, 0x44, 0x12, 0xE4, 0x90, 0x93, 0xE0, 0xF0, 0xA3, 0xF0, 0x7A, 0x93, 0x79, 0xB0, 0x12, -0x54, 0x5C, 0x80, 0x07, 0x90, 0x06, 0x33, 0xE0, 0x44, 0x05, 0xF0, 0x90, 0x93, 0xD2, 0xE0, 0x04, -0xF0, 0xC1, 0x93, 0x90, 0x93, 0xD1, 0xE0, 0x04, 0xF0, 0xC1, 0x77, 0x90, 0x93, 0xD3, 0xE0, 0xFF, -0x22, 0x90, 0x93, 0xA9, 0xE0, 0xFD, 0x90, 0x93, 0xA8, 0xE0, 0x22, 0x90, 0x93, 0xD0, 0xE0, 0xFF, -0xC3, 0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x93, 0xD0, 0xE0, 0x04, 0xF0, 0x22, 0x7E, 0x00, 0x7F, -0x06, 0x02, 0x06, 0x63, 0x7E, 0x00, 0x7F, 0x04, 0x02, 0x06, 0x63, 0x78, 0xAA, 0x7C, 0x93, 0x7D, -0x01, 0x22, 0x7E, 0x00, 0x7F, 0x10, 0x02, 0x06, 0x63, 0x90, 0x8F, 0x61, 0x12, 0x43, 0xFD, 0xE0, -0x22, 0x90, 0x93, 0xA7, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x22, 0x90, 0x93, 0xD4, -0xF1, 0xE4, 0x2F, 0xFF, 0xE4, 0x3E, 0xCF, 0x24, 0x06, 0xCF, 0x12, 0x5F, 0x1B, 0xBF, 0x86, 0x19, -0x90, 0x93, 0xD6, 0xE0, 0xFF, 0x90, 0x93, 0xD5, 0xE0, 0x2F, 0x11, 0x1C, 0xCF, 0x24, 0x07, 0xCF, -0x12, 0x5F, 0x1B, 0xBF, 0xDD, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xFF, 0x90, 0x93, 0xD4, -0xE0, 0x34, 0x00, 0x22, 0x90, 0x94, 0x0F, 0x12, 0x44, 0x12, 0x90, 0x94, 0x12, 0x12, 0x56, 0xE5, -0x75, 0x43, 0x10, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0xD1, 0x12, 0x35, 0x26, 0x90, 0x94, 0x0F, 0x12, -0x56, 0xE5, 0x75, 0x43, 0x10, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0xE1, 0x12, 0x35, 0x26, 0x90, 0x94, -0x15, 0x12, 0x43, 0xE5, 0x90, 0x8F, 0xF1, 0x12, 0x08, 0x6D, 0x90, 0x94, 0x19, 0xE0, 0x90, 0x8F, -0xF8, 0xF0, 0x22, 0x90, 0x8F, 0x36, 0xE0, 0x30, 0xE0, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x06, 0x90, -0xE0, 0x20, 0xE5, 0x10, 0x90, 0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x09, 0x90, 0x01, 0xC7, 0x74, 0x25, -0xF0, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x02, 0x09, 0xE0, 0x90, 0x93, 0xAB, 0xF0, 0x12, -0x06, 0x89, 0x90, 0x93, 0x77, 0x12, 0x75, 0xC9, 0x90, 0x93, 0x78, 0xF0, 0x22, 0x11, 0xDD, 0x90, -0x93, 0x80, 0x12, 0x75, 0xC9, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x81, 0x12, 0x77, 0x7A, 0xFF, 0xED, -0x2F, 0x90, 0x93, 0x82, 0x12, 0x77, 0x82, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x83, 0x12, 0x77, 0xC4, -0xFF, 0xED, 0x2F, 0x90, 0x93, 0x84, 0x12, 0x77, 0xD1, 0xFF, 0xED, 0x2F, 0x90, 0x93, 0x85, 0xF0, -0x12, 0x74, 0xF8, 0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x93, 0x86, 0xF0, 0x22, 0x90, 0x02, 0x09, -0xE0, 0xFD, 0x12, 0x06, 0x89, 0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xFF, -0x12, 0x06, 0x89, 0xFE, 0xEF, 0x2E, 0x90, 0x93, 0x87, 0xF0, 0x22, 0xEF, 0x60, 0x08, 0x90, 0x93, -0x7A, 0xE0, 0xFF, 0x12, 0x57, 0x03, 0x22, 0xEF, 0x60, 0x08, 0x90, 0x93, 0x7F, 0xE0, 0xFF, 0x12, -0x83, 0xF0, 0x22, 0xE4, 0xFD, 0xFC, 0xEF, 0x60, 0x42, 0x90, 0x93, 0x7D, 0x12, 0x67, 0xEB, 0x31, -0x5C, 0x12, 0x77, 0xCB, 0x90, 0x93, 0xAB, 0x12, 0x56, 0xE5, 0x75, 0x43, 0x40, 0x7B, 0x01, 0x7A, -0x90, 0x79, 0x03, 0x12, 0x35, 0x26, 0xE4, 0xFD, 0x7F, 0x03, 0x12, 0x30, 0xCE, 0x90, 0x93, 0x7E, -0xE0, 0x75, 0xF0, 0x80, 0xA4, 0xAE, 0xF0, 0x78, 0x03, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, -0xFF, 0x12, 0x39, 0xD6, 0x7D, 0x01, 0x7F, 0x03, 0x12, 0x30, 0xCE, 0x22, 0x74, 0x00, 0x2F, 0xF9, -0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0xEF, 0x60, 0x0A, 0x90, 0x06, 0x31, 0xE0, 0x44, 0x80, -0xF0, 0x12, 0x63, 0x49, 0x22, 0x31, 0x9A, 0x90, 0x8F, 0x2E, 0xE0, 0xC4, 0x54, 0x0F, 0x30, 0xE0, -0x18, 0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x20, 0xE0, 0x0D, 0x90, 0x95, 0x46, 0x12, -0x08, 0x79, 0x00, 0x00, 0x00, 0x14, 0x12, 0x50, 0x34, 0x22, 0x22, 0x90, 0x93, 0x8D, 0xE0, 0x30, -0xE0, 0x6B, 0x90, 0x93, 0x91, 0xE0, 0x04, 0xF0, 0x90, 0x93, 0x94, 0xE0, 0x64, 0x01, 0x70, 0x20, -0x90, 0x93, 0x8D, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x15, 0x90, 0x93, 0x93, 0xE0, 0x70, -0x0F, 0x90, 0x93, 0x90, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x40, 0x04, 0x51, 0x0E, 0xF0, 0x22, -0x90, 0x93, 0x91, 0xE0, 0xFF, 0x90, 0x93, 0x8E, 0xE0, 0xD3, 0x9F, 0x50, 0x30, 0x90, 0x06, 0x92, -0xE0, 0x20, 0xE2, 0x1A, 0x90, 0x93, 0x93, 0xE0, 0x70, 0x14, 0x7D, 0x08, 0xFF, 0x12, 0x57, 0x87, -0x90, 0x93, 0x92, 0xE0, 0x04, 0xF0, 0x90, 0x93, 0x8C, 0xE0, 0x04, 0xF0, 0x80, 0x06, 0x90, 0x06, -0x92, 0x74, 0x04, 0xF0, 0xE4, 0x90, 0x93, 0x91, 0xF0, 0x90, 0x93, 0x93, 0xF0, 0x22, 0x90, 0x01, -0xC7, 0x74, 0x10, 0xF0, 0x7F, 0x01, 0x12, 0x73, 0xCF, 0x90, 0x93, 0x8D, 0xE0, 0x54, 0xFE, 0x22, -0x90, 0x8E, 0x80, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0x90, 0x8E, 0x8D, 0xF0, 0x90, 0x8E, 0x88, 0xF0, -0x90, 0x8E, 0x81, 0xE0, 0x54, 0xF7, 0xF0, 0x12, 0x6D, 0x9D, 0x7D, 0x02, 0x7F, 0x02, 0x02, 0x6D, -0xA1, 0x90, 0x04, 0x1A, 0xE0, 0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x04, 0x1B, 0xE0, 0x54, -0x07, 0x64, 0x07, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x51, 0x41, 0xEF, 0x64, 0x01, 0x70, -0x47, 0x90, 0x8E, 0x88, 0xE0, 0xFF, 0x54, 0x03, 0x70, 0x3E, 0x90, 0x8E, 0x86, 0xE0, 0xFE, 0xE4, -0xC3, 0x9E, 0x40, 0x34, 0xEF, 0x20, 0xE2, 0x30, 0x90, 0x8E, 0x88, 0xE0, 0x20, 0xE4, 0x29, 0x90, -0x8E, 0x81, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x1E, 0x90, 0x8F, 0x29, 0xE0, 0x70, 0x18, -0x90, 0x06, 0x62, 0xE0, 0x20, 0xE1, 0x11, 0x90, 0x06, 0x62, 0xE0, 0x30, 0xE0, 0x07, 0xE0, 0x54, -0xFC, 0x64, 0x80, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xEF, 0x24, 0xFE, 0x60, 0x0B, -0x04, 0x70, 0x27, 0x90, 0x8E, 0x8A, 0x74, 0x02, 0xF0, 0x80, 0x16, 0xED, 0x70, 0x0A, 0x90, 0x8F, -0x26, 0xE0, 0x90, 0x8E, 0x8A, 0xF0, 0x80, 0x05, 0x90, 0x8E, 0x8A, 0xED, 0xF0, 0x90, 0x8E, 0x8A, -0xE0, 0xA3, 0xF0, 0x90, 0x8E, 0x81, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x8F, 0x2A, 0xE0, 0xC3, -0x13, 0x20, 0xE0, 0x21, 0x90, 0x02, 0x87, 0xE0, 0x70, 0x24, 0x90, 0x8F, 0x2E, 0xE0, 0x30, 0xE0, -0x06, 0x90, 0x02, 0x82, 0xE0, 0x70, 0x17, 0x90, 0x8F, 0x36, 0xE0, 0x20, 0xE0, 0x10, 0x90, 0x02, +0xF0, 0x22, 0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x44, 0x0B, 0xF0, 0x12, 0x87, 0xDD, 0x90, 0x01, +0x98, 0xE0, 0x54, 0xC0, 0x7F, 0x00, 0xB4, 0x40, 0x02, 0x7F, 0x01, 0x22, 0x90, 0x01, 0xC7, 0x74, +0xFE, 0xF0, 0x22, 0x7D, 0x02, 0x90, 0x01, 0xC4, 0x74, 0xD3, 0xF0, 0x74, 0x8B, 0xA3, 0xF0, 0x90, +0x93, 0x27, 0xE0, 0xFF, 0xED, 0xC3, 0x9F, 0x50, 0x10, 0xED, 0x25, 0xE0, 0x24, 0x81, 0xF8, 0xE6, +0x30, 0xE4, 0x03, 0x7F, 0x00, 0x22, 0x0D, 0x80, 0xE6, 0x74, 0xD3, 0x04, 0x90, 0x01, 0xC4, 0xF0, +0x74, 0x8B, 0xA3, 0xF0, 0x7F, 0x01, 0x22, 0xE4, 0x90, 0x8D, 0x01, 0x12, 0x4D, 0xB3, 0xA3, 0xF0, +0x22, 0x90, 0x01, 0xE4, 0x74, 0x1F, 0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x34, 0xE0, 0x55, +0x15, 0xF5, 0x19, 0xA3, 0xE0, 0x55, 0x16, 0xF5, 0x1A, 0xA3, 0xE0, 0x55, 0x17, 0xF5, 0x1B, 0xA3, +0xE0, 0x55, 0x18, 0xF5, 0x1C, 0x90, 0x01, 0x34, 0xE5, 0x19, 0xF0, 0xA3, 0xE5, 0x1A, 0xF0, 0xA3, +0xE5, 0x1B, 0xF0, 0xA3, 0xE5, 0x1C, 0xF0, 0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x1D, 0xF5, 0x21, +0xA3, 0xE0, 0x55, 0x1E, 0xF5, 0x22, 0xA3, 0xE0, 0x55, 0x1F, 0xF5, 0x23, 0xA3, 0xE0, 0x55, 0x20, +0xF5, 0x24, 0x90, 0x01, 0x3C, 0xE5, 0x21, 0xF0, 0xA3, 0xE5, 0x22, 0xF0, 0xA3, 0xE5, 0x23, 0xF0, +0xA3, 0xE5, 0x24, 0xF0, 0x53, 0x91, 0xDF, 0x22, 0x90, 0x8E, 0xC4, 0xE0, 0x30, 0xE0, 0x05, 0x7F, +0x10, 0x12, 0x71, 0xDE, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90, 0x93, 0xF8, 0xF0, 0xE0, 0xFF, 0x30, +0xE0, 0x07, 0x90, 0x01, 0xCF, 0xE0, 0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE5, 0x23, 0x90, 0x01, 0xCF, +0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0xE4, 0xF5, 0xA8, 0xF5, 0xE8, 0x12, +0x4D, 0x6E, 0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x49, 0x39, 0x80, 0xFE, +0x22, 0x90, 0x8E, 0x15, 0xE0, 0x60, 0x46, 0x90, 0x8E, 0x11, 0xE0, 0x30, 0xE0, 0x18, 0x90, 0x8E, +0x2C, 0xE0, 0x04, 0x12, 0x77, 0x6B, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90, 0x8E, +0x4C, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x77, 0x48, 0x30, 0xE0, 0x0A, 0x90, 0x01, 0x3B, 0xE0, +0x30, 0xE4, 0x03, 0x12, 0x76, 0x1D, 0x90, 0x95, 0x29, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80, +0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0x44, 0x01, 0xF0, 0xB1, 0xAF, 0xB1, +0x72, 0xE4, 0x90, 0x93, 0x2B, 0xF0, 0x12, 0x77, 0x7A, 0x12, 0x6F, 0xFA, 0x30, 0xE0, 0x52, 0x90, +0x90, 0x74, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x7C, 0x00, 0x7D, 0x64, 0x12, 0x07, 0x15, 0x90, 0x90, +0xC8, 0xE0, 0x6E, 0x70, 0x03, 0xA3, 0xE0, 0x6F, 0x60, 0x0A, 0x90, 0x90, 0xC8, 0xE4, 0x75, 0xF0, +0x01, 0x02, 0x08, 0xD6, 0x90, 0x90, 0x78, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x90, 0x86, 0xE0, +0xB5, 0x06, 0x14, 0xA3, 0xE0, 0xB5, 0x07, 0x0F, 0xEF, 0x4E, 0x60, 0x0B, 0x90, 0x01, 0xC7, 0x74, +0x31, 0xF0, 0x7F, 0x01, 0x02, 0x79, 0x21, 0x12, 0x61, 0xA1, 0xE4, 0x90, 0x90, 0xC8, 0xF0, 0xA3, +0xF0, 0x22, 0x90, 0x93, 0x28, 0xE0, 0x30, 0xE0, 0x35, 0x12, 0x73, 0x13, 0x70, 0x30, 0x90, 0x95, +0x2C, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x0B, 0x90, 0x93, 0x2A, 0xE0, 0x04, 0xF0, 0xE4, 0x90, +0x95, 0x2C, 0xF0, 0x90, 0x93, 0x2A, 0xE0, 0xFF, 0x90, 0x93, 0x29, 0xE0, 0xD3, 0x9F, 0x50, 0x0E, +0x90, 0x93, 0x2B, 0xE0, 0x70, 0x08, 0xE4, 0x90, 0x93, 0x2A, 0xF0, 0x12, 0x67, 0x94, 0x22, 0x90, +0x93, 0x2C, 0xE0, 0x30, 0xE0, 0x6C, 0x90, 0x93, 0x30, 0xE0, 0x04, 0xF0, 0x90, 0x93, 0x33, 0xE0, +0x64, 0x01, 0x70, 0x21, 0x90, 0x93, 0x2C, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x16, 0x90, +0x93, 0x32, 0xE0, 0x70, 0x10, 0x90, 0x93, 0x2F, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x40, 0x05, +0x12, 0x79, 0x6A, 0xF0, 0x22, 0x90, 0x93, 0x30, 0xE0, 0xFF, 0x90, 0x93, 0x2D, 0xE0, 0xD3, 0x9F, +0x50, 0x30, 0x90, 0x06, 0x92, 0xE0, 0x20, 0xE2, 0x1A, 0x90, 0x93, 0x32, 0xE0, 0x70, 0x14, 0x7D, +0x08, 0xFF, 0x12, 0x65, 0x59, 0x90, 0x93, 0x31, 0xE0, 0x04, 0xF0, 0x90, 0x93, 0x2B, 0xE0, 0x04, +0xF0, 0x80, 0x06, 0x90, 0x06, 0x92, 0x74, 0x04, 0xF0, 0xE4, 0x90, 0x93, 0x30, 0xF0, 0x90, 0x93, +0x32, 0xF0, 0x22, 0x90, 0x93, 0x32, 0xE0, 0x04, 0xF0, 0x90, 0x8E, 0x18, 0xE0, 0x64, 0x02, 0x60, +0x03, 0x12, 0x75, 0x82, 0x22, 0x90, 0x8E, 0x15, 0xE0, 0x60, 0x02, 0xD1, 0x3E, 0x22, 0x90, 0x8E, +0x15, 0xE0, 0x64, 0x01, 0x70, 0x14, 0x12, 0x77, 0xF5, 0x60, 0x06, 0x12, 0x53, 0xD0, 0x02, 0x67, +0xAC, 0x90, 0x8E, 0x18, 0xE0, 0x70, 0x03, 0x12, 0x51, 0xF9, 0x22, 0x90, 0x8E, 0x15, 0xE0, 0x60, +0x03, 0x12, 0x74, 0x47, 0x22, 0x90, 0x8E, 0x15, 0xE0, 0x60, 0x10, 0x90, 0x06, 0x92, 0xE0, 0x30, +0xE1, 0x03, 0x02, 0x67, 0xAC, 0x12, 0x75, 0x6E, 0x12, 0x74, 0xB2, 0x22, 0xF1, 0x24, 0x90, 0x93, +0xFD, 0xEF, 0xF0, 0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x4E, +0xB5, 0x90, 0x93, 0xFD, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, +0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0xF1, 0x1B, 0x90, 0x8E, 0x2E, 0xE0, 0xFB, +0xAC, 0x07, 0x90, 0x8E, 0x11, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x8E, 0x4B, 0xE0, 0x24, 0x04, 0x90, +0x8E, 0x2A, 0xF0, 0x90, 0x8E, 0x4B, 0xE0, 0x24, 0x03, 0x90, 0x8E, 0x29, 0xF0, 0x80, 0x0B, 0x90, +0x8E, 0x2A, 0x74, 0x02, 0xF0, 0x90, 0x8E, 0x29, 0x14, 0xF0, 0x90, 0x8E, 0x29, 0xE0, 0xFA, 0x90, +0x8E, 0x28, 0xE0, 0xD3, 0x9A, 0x50, 0x09, 0x90, 0x8E, 0x1D, 0xEB, 0xF1, 0x13, 0x2C, 0x80, 0x0B, +0xAD, 0x02, 0xC3, 0xED, 0x9D, 0x2B, 0x90, 0x8E, 0x1D, 0xF1, 0x13, 0x90, 0x8E, 0x2D, 0xF0, 0x90, +0x8E, 0x2D, 0xE0, 0xFF, 0x7E, 0x00, 0x90, 0x8E, 0x21, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x05, +0x58, 0xF0, 0x22, 0xF0, 0x90, 0x8E, 0x2A, 0xE0, 0xC3, 0x9D, 0x22, 0x90, 0x8E, 0x27, 0xE0, 0xFF, +0xA3, 0xE0, 0xFD, 0x22, 0xE4, 0x90, 0x93, 0xFE, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x7F, 0x83, 0x12, +0x4A, 0x4E, 0x90, 0x93, 0xFE, 0xEF, 0xF0, 0x7F, 0x83, 0x12, 0x4A, 0x4E, 0xAE, 0x07, 0x90, 0x93, +0xFE, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3, 0x90, 0x94, 0x00, 0xE0, 0x94, 0x64, 0x90, 0x93, +0xFF, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x93, 0xFE, +0xE0, 0xFF, 0x22, 0x90, 0x93, 0xFF, 0x12, 0x61, 0x77, 0x80, 0xC2, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1A, 0x90, 0x05, 0x22, 0xE0, 0x54, 0x90, 0x60, 0x07, +0x90, 0x01, 0xC0, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE1, 0xE4, 0x7F, 0x00, +0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xC3, 0xEE, 0x94, 0x01, 0x40, 0x0A, 0x0D, +0xED, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0xE4, 0x2F, 0xFF, 0x22, 0x90, 0x93, 0x71, 0xE0, 0x2F, 0xFF, +0x90, 0x93, 0x70, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x93, 0xF4, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, +0x1B, 0xE0, 0xFD, 0xF1, 0x99, 0x90, 0x93, 0x6B, 0xEF, 0xF0, 0x22, 0x7F, 0xFF, 0x12, 0x53, 0xD9, +0xE4, 0x90, 0x95, 0x1E, 0xF0, 0xA3, 0xF0, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x0F, 0xA3, 0xE0, 0x70, +0x0B, 0xA3, 0xE0, 0x70, 0x07, 0xA3, 0xE0, 0x70, 0x03, 0x7F, 0x01, 0x22, 0xD3, 0x90, 0x95, 0x1F, +0xE0, 0x94, 0xE8, 0x90, 0x95, 0x1E, 0xE0, 0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC0, 0xE0, 0x44, +0x20, 0xF0, 0x7F, 0x00, 0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x3E, 0x50, 0x90, 0x95, 0x1E, 0x12, +0x61, 0x77, 0x80, 0xC3, 0x90, 0x01, 0xC4, 0x74, 0x14, 0xF0, 0x74, 0x90, 0xA3, 0xF0, 0x7F, 0x90, +0x12, 0x4A, 0x4E, 0xEF, 0x20, 0xE0, 0xF7, 0x74, 0x14, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x90, +0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0xEF, 0x12, 0x51, 0x5B, +0xE4, 0xF0, 0x0F, 0xEF, 0xB4, 0x08, 0xF5, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0x53, 0xE4, +0xF0, 0xFF, 0xEF, 0x12, 0x51, 0x5B, 0xE4, 0xF0, 0x0F, 0xEF, 0xB4, 0x08, 0xF5, 0x22, 0x7B, 0x01, +0x7A, 0x93, 0x79, 0x3B, 0x7F, 0xFB, 0x7E, 0x01, 0x12, 0x34, 0xC1, 0xBF, 0x01, 0x16, 0x90, 0x93, +0x3B, 0xE0, 0x54, 0x30, 0xFF, 0xBF, 0x20, 0x07, 0x90, 0x93, 0x34, 0x74, 0x01, 0xF0, 0x22, 0xE4, +0x90, 0x93, 0x34, 0xF0, 0x22, 0x12, 0x7F, 0x59, 0x90, 0x93, 0x28, 0x12, 0x7F, 0xCC, 0x54, 0x04, +0xFF, 0xEE, 0x54, 0xFB, 0x4F, 0xF0, 0x12, 0x06, 0x89, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, 0x77, +0xC3, 0x90, 0x93, 0x29, 0xF0, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x02, 0x84, 0xEF, 0xF0, +0xEE, 0xA3, 0xF0, 0xA3, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0xE4, 0x90, 0x95, 0x22, 0xF0, 0xA3, 0xF0, +0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x24, 0xC3, 0x90, 0x95, 0x23, 0xE0, 0x94, 0xD0, 0x90, 0x95, +0x22, 0xE0, 0x94, 0x07, 0x40, 0x0A, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x00, 0x22, +0x90, 0x95, 0x22, 0x12, 0x61, 0x77, 0x12, 0x87, 0xDD, 0x80, 0xD5, 0x7F, 0x01, 0x22, 0x90, 0x02, +0x86, 0xE0, 0x20, 0xE2, 0x03, 0x7F, 0x04, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x7F, 0x01, 0x20, 0xE1, +0x02, 0x7F, 0x02, 0x22, 0x90, 0x8E, 0xCD, 0xE0, 0xFF, 0x20, 0xE0, 0x07, 0x90, 0x01, 0x3F, 0xE0, +0x30, 0xE2, 0x14, 0xEF, 0x44, 0x01, 0x90, 0x8E, 0xCD, 0xF0, 0x90, 0x8E, 0xC7, 0xE0, 0xC4, 0x54, +0x0F, 0x20, 0xE0, 0x03, 0x7F, 0x00, 0x22, 0x7F, 0x01, 0x22, 0xEF, 0x90, 0x01, 0xC7, 0xB4, 0xA0, +0x05, 0x74, 0x04, 0xF0, 0x80, 0x03, 0x74, 0x08, 0xF0, 0x02, 0x6F, 0x98, 0x90, 0x93, 0x56, 0x31, +0x98, 0x90, 0x93, 0x5E, 0xF0, 0x90, 0x93, 0x5E, 0xE0, 0xFD, 0xC3, 0x94, 0x06, 0x50, 0x28, 0x90, +0x93, 0x57, 0xE0, 0x24, 0x04, 0xFF, 0x90, 0x93, 0x56, 0xE0, 0x34, 0x00, 0xFE, 0x12, 0x6B, 0x77, +0x90, 0x93, 0x5E, 0xE0, 0x24, 0x58, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xEF, 0xF0, 0x90, +0x93, 0x5E, 0xE0, 0x04, 0xF0, 0x80, 0xCE, 0x78, 0xCE, 0x7C, 0x8E, 0x7D, 0x01, 0x7B, 0x01, 0x7A, +0x93, 0x79, 0x58, 0x31, 0x8C, 0x7F, 0x00, 0x70, 0x02, 0x7F, 0x01, 0x22, 0x7E, 0x00, 0x7F, 0x06, +0x12, 0x45, 0xC7, 0xEF, 0x22, 0x90, 0x93, 0x46, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x22, 0x90, +0x93, 0x4A, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x93, 0x48, 0x31, 0x98, 0x90, 0x93, 0x6E, 0xF0, +0xEF, 0x24, 0x24, 0xFF, 0xE4, 0x3E, 0xFE, 0xC0, 0x06, 0x91, 0x20, 0xD0, 0x06, 0xE4, 0xFB, 0xFA, +0x71, 0xF0, 0x4E, 0x60, 0x3E, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x93, 0x6F, 0x12, 0x6D, 0x70, 0x90, +0x93, 0x4D, 0x91, 0x09, 0x90, 0x93, 0x4D, 0x71, 0xFF, 0xFE, 0xC3, 0x9F, 0x50, 0x25, 0x90, 0x93, +0x70, 0xE0, 0x24, 0x02, 0xFD, 0x90, 0x93, 0x6F, 0xE0, 0x34, 0x00, 0xFC, 0xEE, 0x7E, 0x00, 0x2D, +0x12, 0x6B, 0x71, 0x90, 0x93, 0x4C, 0xE0, 0x24, 0x4E, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0x12, 0x5D, +0x87, 0x80, 0xD1, 0x91, 0x11, 0xC0, 0x06, 0x91, 0x20, 0xD0, 0x06, 0x7B, 0x03, 0x71, 0xED, 0x90, +0x93, 0x49, 0xE0, 0x24, 0x22, 0x91, 0x17, 0x90, 0x93, 0x6F, 0x12, 0x6F, 0xEB, 0xEF, 0x20, 0xE4, +0x02, 0x41, 0xD5, 0x90, 0x93, 0x6E, 0xE0, 0x04, 0xF0, 0x91, 0x11, 0xC0, 0x06, 0x91, 0x20, 0xD0, +0x06, 0x7B, 0x30, 0x71, 0xED, 0x4E, 0x60, 0x45, 0xE0, 0x24, 0x08, 0xFF, 0x90, 0x93, 0x6F, 0x12, +0x6D, 0x70, 0x91, 0x06, 0x71, 0xFC, 0xC3, 0x9F, 0x50, 0x33, 0x90, 0x93, 0x70, 0xE0, 0x24, 0x0D, +0xFF, 0x90, 0x93, 0x6F, 0x12, 0x6D, 0x70, 0x90, 0x93, 0x71, 0xEF, 0xF0, 0xBF, 0x02, 0x09, 0x90, +0x93, 0x6E, 0xE0, 0x24, 0x20, 0xF0, 0x80, 0x0E, 0x90, 0x93, 0x71, 0xE0, 0xB4, 0x04, 0x07, 0x90, +0x93, 0x6E, 0xE0, 0x24, 0x40, 0xF0, 0x91, 0x3E, 0x12, 0x5D, 0x8B, 0x80, 0xC7, 0x91, 0x11, 0xC0, +0x06, 0x91, 0x20, 0xD0, 0x06, 0x7B, 0xDD, 0x7A, 0x00, 0x7D, 0x01, 0x71, 0xF1, 0x4E, 0x60, 0x4A, +0xE0, 0x24, 0x0C, 0xFF, 0x90, 0x93, 0x6F, 0x12, 0x6D, 0x70, 0x91, 0x06, 0x71, 0xFC, 0xC3, 0x9F, +0x50, 0x38, 0x90, 0x93, 0x70, 0xE0, 0x24, 0x11, 0xFF, 0x90, 0x93, 0x6F, 0x12, 0x6D, 0x70, 0x90, +0x93, 0x71, 0xEF, 0xF0, 0xBF, 0x02, 0x09, 0x90, 0x93, 0x6E, 0xE0, 0x24, 0x02, 0xF0, 0x80, 0x0E, +0x90, 0x93, 0x71, 0xE0, 0xB4, 0x04, 0x07, 0x90, 0x93, 0x6E, 0xE0, 0x24, 0x04, 0xF0, 0x91, 0x3E, +0x12, 0x5D, 0x8B, 0x80, 0xC7, 0xE4, 0x90, 0x93, 0x6E, 0xF0, 0x90, 0x90, 0xCA, 0xE0, 0x90, 0x04, +0xFD, 0x91, 0x0A, 0x90, 0x90, 0xCA, 0x71, 0xFF, 0xFE, 0xC3, 0x9F, 0x50, 0x6C, 0xD1, 0x84, 0xF5, +0x83, 0xE0, 0xFF, 0x90, 0x93, 0x4D, 0xE0, 0xFE, 0x6F, 0x70, 0x59, 0x90, 0x04, 0xFC, 0xE0, 0x04, +0xF0, 0x90, 0x93, 0x4C, 0xE0, 0x24, 0xEA, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE0, 0xFF, +0x90, 0x93, 0x6E, 0xE0, 0xFD, 0x4F, 0x60, 0x04, 0xED, 0x5F, 0x60, 0x38, 0xEE, 0xFF, 0x7E, 0x00, +0xC0, 0x06, 0xC0, 0x07, 0x90, 0x93, 0x4C, 0xE0, 0x75, 0xF0, 0x20, 0xA4, 0x24, 0x12, 0xF9, 0x74, +0x91, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x78, 0x4E, 0x7C, 0x93, 0x7D, 0x01, 0xD0, 0x07, 0xD0, 0x06, +0x12, 0x45, 0xC7, 0xEF, 0x70, 0x0E, 0x90, 0x01, 0xC7, 0x74, 0x55, 0xF0, 0x7F, 0x01, 0x12, 0x79, +0x21, 0x12, 0x87, 0xC6, 0x12, 0x5D, 0x8B, 0x80, 0x8A, 0x22, 0x90, 0x93, 0x73, 0xD1, 0x66, 0xA3, +0xEA, 0xF0, 0xA3, 0xEB, 0xF0, 0xC3, 0x90, 0x93, 0x79, 0xE0, 0x94, 0x01, 0x90, 0x93, 0x78, 0xE0, +0x94, 0x00, 0x50, 0x02, 0x80, 0x73, 0xE4, 0x90, 0x93, 0x7C, 0xF0, 0xA3, 0xF0, 0x91, 0x35, 0xE4, +0xFD, 0x12, 0x6B, 0x77, 0x90, 0x93, 0x76, 0xE0, 0x70, 0x03, 0xA3, 0xE0, 0x6F, 0x70, 0x17, 0x90, +0x93, 0x74, 0xE0, 0x24, 0x02, 0x91, 0x60, 0xFE, 0x90, 0x93, 0x75, 0xE0, 0xFD, 0xD1, 0xA8, 0xBF, +0x01, 0x02, 0x81, 0x35, 0x80, 0x00, 0x90, 0x93, 0x74, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x93, 0x73, +0x12, 0x6D, 0x70, 0x7E, 0x00, 0x90, 0x93, 0x7A, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x24, 0x02, 0xFF, +0xEE, 0x33, 0xFE, 0x90, 0x93, 0x73, 0x8F, 0xF0, 0x12, 0x08, 0xD6, 0x90, 0x93, 0x7C, 0xEE, 0x8F, +0xF0, 0x12, 0x08, 0xD6, 0x90, 0x93, 0x78, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x93, 0x7D, +0xE0, 0x9F, 0x90, 0x93, 0x7C, 0xE0, 0x9E, 0x40, 0x94, 0xE4, 0xFE, 0xFF, 0x22, 0x7A, 0x00, 0xE4, +0xFD, 0x71, 0x5A, 0x90, 0x93, 0x6F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x93, 0x72, 0xE0, +0xFF, 0x90, 0x93, 0x4C, 0xE0, 0x22, 0x90, 0x93, 0x72, 0xEF, 0xF0, 0xE4, 0x90, 0x93, 0x4C, 0xF0, +0x22, 0x90, 0x93, 0x49, 0xE0, 0x24, 0x24, 0xFF, 0x90, 0x93, 0x48, 0xE0, 0x34, 0x00, 0xFE, 0x22, +0x90, 0x93, 0x4B, 0xE0, 0x24, 0xDC, 0xFE, 0x90, 0x93, 0x4A, 0xE0, 0x34, 0xFF, 0x90, 0x93, 0x78, +0xF0, 0xA3, 0xCE, 0xF0, 0x22, 0x90, 0x93, 0x73, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x93, +0x6F, 0xE4, 0x75, 0xF0, 0x04, 0x02, 0x08, 0xD6, 0xD1, 0x7B, 0x90, 0x94, 0x51, 0xE0, 0x64, 0x01, +0xF0, 0xE0, 0x24, 0x48, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x94, 0xA3, 0x12, 0x6C, 0x21, 0x21, 0x9F, +0xFF, 0x90, 0x93, 0x73, 0xE0, 0x34, 0x00, 0x22, 0x90, 0x93, 0x73, 0xD1, 0x66, 0x2F, 0xFF, 0xE4, +0x3E, 0xCF, 0x24, 0x06, 0xCF, 0x12, 0x6D, 0x71, 0xBF, 0x86, 0x19, 0x90, 0x93, 0x75, 0xE0, 0xFF, +0x90, 0x93, 0x74, 0xE0, 0x2F, 0x91, 0x60, 0xCF, 0x24, 0x07, 0xCF, 0x12, 0x6D, 0x71, 0xBF, 0xDD, +0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xD1, 0x63, 0x12, 0x6F, 0xF3, 0x7B, 0xFF, 0x7A, 0x40, +0x79, 0x6A, 0x12, 0x57, 0xF5, 0xD1, 0x9F, 0x7A, 0x40, 0x79, 0x70, 0xD1, 0x40, 0x78, 0x5F, 0x7C, +0x93, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0x80, 0xD1, 0x40, 0xE4, 0x90, 0x93, 0x72, 0x12, +0x6C, 0x21, 0xA3, 0xE0, 0xFD, 0x91, 0x68, 0xEF, 0x64, 0x01, 0x60, 0x02, 0xC1, 0x28, 0x12, 0x6E, +0xA4, 0xCF, 0x24, 0x0E, 0xCF, 0x12, 0x6D, 0x71, 0xEF, 0x64, 0x3A, 0x60, 0x02, 0xC1, 0x28, 0x12, +0x6E, 0xA4, 0xCF, 0x24, 0x30, 0xCF, 0x12, 0x6D, 0x71, 0xEF, 0x64, 0x87, 0x60, 0x02, 0xC1, 0x28, +0x90, 0x93, 0x72, 0x04, 0xF0, 0xE4, 0x90, 0x93, 0x6F, 0xF0, 0xD1, 0x2E, 0x94, 0x10, 0x50, 0x1A, +0xD1, 0x6F, 0x12, 0x6E, 0xAF, 0xCD, 0x24, 0x38, 0x12, 0x6B, 0x69, 0x90, 0x93, 0x6F, 0xE0, 0x24, +0x5F, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xD1, 0x35, 0x80, 0xE0, 0xE4, 0x90, 0x93, 0x70, 0xF0, 0x90, +0x93, 0x70, 0xE0, 0xFF, 0xC3, 0x94, 0x02, 0x40, 0x02, 0xC1, 0x28, 0x75, 0xF0, 0x38, 0xEF, 0xD1, +0x47, 0x20, 0xE0, 0x02, 0xC1, 0x28, 0xE4, 0x90, 0x93, 0x71, 0xF0, 0xD1, 0x4F, 0x90, 0x8E, 0xF9, +0x12, 0x43, 0xFD, 0xE0, 0xFE, 0x90, 0x93, 0x71, 0xE0, 0xC3, 0x9E, 0x40, 0x02, 0xC1, 0x20, 0xEF, +0x75, 0xF0, 0x38, 0xA4, 0x24, 0x10, 0xF9, 0x74, 0x8F, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xE0, 0x75, +0xF0, 0x10, 0xA4, 0x29, 0xF9, 0xEA, 0x35, 0xF0, 0xFA, 0x78, 0x5F, 0x7C, 0x93, 0xD1, 0x58, 0x60, +0x02, 0xC1, 0x11, 0x90, 0x06, 0x33, 0xE0, 0x44, 0x01, 0x54, 0xFB, 0xF0, 0xE4, 0x90, 0x93, 0x6F, +0xF0, 0xD1, 0x2E, 0x94, 0x06, 0x50, 0x14, 0xD1, 0x6F, 0x12, 0x6E, 0xAF, 0xCD, 0x24, 0x4A, 0x12, +0x6B, 0x69, 0x90, 0x93, 0x6F, 0xD1, 0x96, 0xD1, 0x35, 0x80, 0xE6, 0xE4, 0x90, 0x93, 0x6F, 0xF0, +0xD1, 0x2E, 0x94, 0x10, 0x50, 0x0C, 0x12, 0x6B, 0x55, 0x90, 0x93, 0x6F, 0xD1, 0x8D, 0xD1, 0x35, +0x80, 0xEE, 0xD1, 0x4F, 0xD1, 0x47, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x19, 0xEF, 0x75, 0xF0, 0x38, +0xA4, 0x24, 0x00, 0xF9, 0x74, 0x8F, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x78, 0x4F, 0x7C, 0x93, 0xD1, +0x58, 0x70, 0x45, 0x80, 0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x49, 0x90, 0x93, 0x76, 0x12, 0x44, +0x12, 0x7A, 0x93, 0x79, 0x5F, 0x90, 0x93, 0x79, 0x12, 0x44, 0x12, 0x90, 0x93, 0x70, 0xE0, 0x75, +0xF0, 0x38, 0xA4, 0x24, 0xFA, 0xF9, 0x74, 0x8E, 0x35, 0xF0, 0xFA, 0x90, 0x93, 0x7C, 0x12, 0x44, +0x12, 0xE4, 0x90, 0x93, 0x7F, 0xF0, 0xA3, 0xF0, 0x7A, 0x93, 0x79, 0x4F, 0x12, 0x53, 0xE4, 0x80, +0x07, 0x90, 0x06, 0x33, 0xE0, 0x44, 0x05, 0xF0, 0x90, 0x93, 0x71, 0xE0, 0x04, 0xF0, 0xA1, 0x3B, +0x90, 0x93, 0x70, 0xE0, 0x04, 0xF0, 0xA1, 0x1F, 0x90, 0x93, 0x72, 0xE0, 0xFF, 0x22, 0x90, 0x93, +0x6F, 0xE0, 0xFF, 0xC3, 0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x93, 0x6F, 0xE0, 0x04, 0xF0, 0x22, +0x7E, 0x00, 0x7F, 0x10, 0x02, 0x06, 0x63, 0x90, 0x8E, 0xF8, 0x12, 0x43, 0xFD, 0xE0, 0x22, 0x90, +0x93, 0x70, 0xE0, 0xFF, 0x75, 0xF0, 0x38, 0x22, 0x7D, 0x01, 0x7E, 0x00, 0x7F, 0x10, 0x12, 0x45, +0xC7, 0xEF, 0x22, 0x90, 0x93, 0x46, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x22, 0x90, +0x93, 0x48, 0xE0, 0xFD, 0x90, 0x93, 0x47, 0xE0, 0x2D, 0xFD, 0x22, 0x90, 0x93, 0x46, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0x22, 0x74, 0xDA, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0x22, 0xE0, 0x24, 0x4F, +0xF5, 0x82, 0xE4, 0x34, 0x93, 0x22, 0xE0, 0x24, 0x49, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0x22, 0x78, +0x4F, 0x7C, 0x93, 0x7D, 0x01, 0x7B, 0xFF, 0x22, 0xED, 0x14, 0x60, 0x06, 0x04, 0x70, 0x03, 0x7F, +0x01, 0x22, 0x7F, 0x01, 0x22, 0x31, 0x95, 0xA3, 0xF0, 0x90, 0x93, 0x48, 0xE0, 0xFD, 0xC3, 0x94, +0x04, 0x50, 0x29, 0x90, 0x93, 0x47, 0xE0, 0x24, 0x10, 0x12, 0x6E, 0xAE, 0xFE, 0x12, 0x6B, 0x77, +0x90, 0x93, 0x48, 0xE0, 0x24, 0x80, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE0, 0x6F, 0x60, +0x03, 0x7F, 0x00, 0x22, 0x90, 0x93, 0x48, 0xE0, 0x04, 0xF0, 0x80, 0xCD, 0x7F, 0x01, 0x22, 0xD1, +0x63, 0xE4, 0xA3, 0xF0, 0xF1, 0x2A, 0x50, 0x1A, 0x12, 0x6C, 0x22, 0xF1, 0x79, 0x24, 0xA8, 0xF5, +0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE0, 0xB5, 0x07, 0x1D, 0x90, 0x93, 0x49, 0xE0, 0x04, 0xF0, +0x80, 0xE2, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0x30, 0xF0, 0x7F, +0x01, 0x12, 0x79, 0x21, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x93, 0x49, 0xE0, 0xFD, 0xC3, +0x94, 0x02, 0x22, 0xD1, 0x63, 0x90, 0x90, 0x7A, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x60, 0x26, 0xE4, +0x90, 0x93, 0x49, 0xF0, 0xF1, 0x2A, 0x50, 0x20, 0x12, 0x6C, 0x22, 0xF1, 0x79, 0x24, 0x88, 0xF5, +0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE0, 0x6F, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x93, 0x49, +0xE0, 0x04, 0xF0, 0x80, 0xDF, 0x7F, 0x00, 0x22, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x40, 0xF0, 0xE4, +0x90, 0x90, 0x86, 0xF0, 0xA3, 0xF0, 0x7F, 0x01, 0x22, 0xED, 0x24, 0x1C, 0xFD, 0x12, 0x6B, 0x77, +0x90, 0x93, 0x49, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xEF, 0x20, 0xE0, 0x05, +0x90, 0x93, 0x16, 0x80, 0x03, 0x90, 0x93, 0x17, 0xE0, 0x90, 0x8F, 0x99, 0xF0, 0x90, 0x8F, 0x99, +0xE0, 0x14, 0x60, 0x13, 0x14, 0x60, 0x14, 0x24, 0xFE, 0x60, 0x10, 0x14, 0x60, 0x09, 0x14, 0x60, +0x06, 0x24, 0x06, 0xE4, 0xFE, 0x80, 0x06, 0x7E, 0x04, 0x80, 0x02, 0x7E, 0x08, 0xAF, 0x06, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0xA3, 0xE0, 0xFE, 0x24, 0x28, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, +0xE0, 0xFF, 0x74, 0x29, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFD, 0x74, 0x2C, +0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, 0x30, 0xE7, 0x04, +0x7C, 0x02, 0x80, 0x02, 0xE4, 0xFC, 0xED, 0x30, 0xE6, 0x08, 0xAF, 0x03, 0xF1, 0x85, 0xAE, 0x07, +0x80, 0x02, 0xE4, 0xFE, 0xEC, 0x24, 0x18, 0x2E, 0xFF, 0x22, 0x90, 0x94, 0xED, 0xED, 0xF0, 0x90, +0x94, 0xEA, 0x12, 0x44, 0x12, 0xE4, 0x90, 0x94, 0xEE, 0xF0, 0xA3, 0xF0, 0x12, 0x06, 0x89, 0xFF, +0x12, 0x77, 0xC3, 0xFD, 0x12, 0x7D, 0x70, 0xFB, 0x12, 0x97, 0xEA, 0x90, 0x94, 0xEE, 0xEF, 0xF0, +0x90, 0x94, 0xEA, 0x12, 0x44, 0x09, 0x12, 0x7D, 0x70, 0xFF, 0x12, 0x97, 0x85, 0x90, 0x94, 0xEF, +0xEF, 0xF0, 0x90, 0x8F, 0x99, 0xE0, 0x24, 0xFE, 0x60, 0x14, 0x24, 0xFE, 0x60, 0x10, 0x14, 0x60, +0x07, 0x14, 0x60, 0x04, 0x24, 0x05, 0x70, 0x41, 0x11, 0x9A, 0x11, 0xA6, 0x80, 0x0D, 0x11, 0x9A, +0x90, 0x8F, 0x99, 0xE0, 0x90, 0x94, 0xBF, 0xF0, 0x12, 0x7C, 0x99, 0x90, 0x94, 0xEF, 0xE0, 0xFF, +0x90, 0x94, 0xEA, 0x12, 0x44, 0x09, 0x90, 0x94, 0xEE, 0xE0, 0x7C, 0x00, 0x29, 0xF9, 0xEC, 0x3A, +0xFA, 0xC3, 0xE9, 0x9F, 0xF9, 0xEA, 0x94, 0x00, 0xFA, 0x75, 0x40, 0x01, 0x75, 0x41, 0x8F, 0x75, +0x42, 0x90, 0xA3, 0xE0, 0xF5, 0x43, 0x12, 0x35, 0x26, 0x22, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x90, +0x90, 0x94, 0xED, 0xE0, 0xFD, 0x22, 0x90, 0x94, 0xD9, 0xED, 0xF0, 0x90, 0x94, 0xD6, 0x12, 0x44, +0x12, 0x12, 0x7D, 0xF8, 0x90, 0x94, 0xDD, 0xF0, 0x90, 0x94, 0xD6, 0x12, 0x56, 0x7A, 0x75, 0x43, +0x03, 0x7B, 0x01, 0x7A, 0x94, 0x79, 0xDA, 0x12, 0x35, 0x26, 0x90, 0x94, 0xD9, 0xE0, 0x70, 0x2E, +0xFF, 0x11, 0xFF, 0xE0, 0xB4, 0xFF, 0x06, 0x11, 0xFF, 0xE4, 0xF0, 0x80, 0x07, 0x11, 0xFF, 0xE0, +0x04, 0xF0, 0x80, 0x05, 0x0F, 0xEF, 0xB4, 0x03, 0xE8, 0x75, 0x40, 0x01, 0x75, 0x41, 0x94, 0x75, +0x42, 0xDA, 0x75, 0x43, 0x03, 0x90, 0x94, 0xD6, 0x12, 0x44, 0x09, 0x12, 0x35, 0x26, 0x22, 0x74, +0xDA, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x94, 0xF5, 0x83, 0x22, 0x31, 0x1B, 0x12, 0x57, 0x00, 0x75, +0x43, 0x08, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x90, 0x02, 0x35, 0x26, 0x12, 0x57, 0xD3, 0x7E, 0x00, +0x74, 0x00, 0x2F, 0x22, 0x31, 0x1B, 0x12, 0x57, 0x00, 0x75, 0x43, 0x70, 0x7B, 0x01, 0x7A, 0x8E, +0x79, 0xF8, 0x02, 0x35, 0x26, 0xEF, 0x60, 0x07, 0x90, 0x93, 0x1E, 0xE0, 0xFF, 0x31, 0x24, 0x22, +0x90, 0x93, 0xAD, 0x12, 0x44, 0x12, 0x90, 0x93, 0xB0, 0x12, 0x56, 0x7A, 0x75, 0x43, 0x10, 0x7B, +0x01, 0x7A, 0x8F, 0x79, 0x68, 0x12, 0x35, 0x26, 0x90, 0x93, 0xAD, 0x12, 0x56, 0x7A, 0x75, 0x43, +0x10, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x78, 0x12, 0x35, 0x26, 0x90, 0x93, 0xB3, 0x12, 0x43, 0xE5, +0x90, 0x8F, 0x88, 0x12, 0x08, 0x6D, 0x90, 0x93, 0xB7, 0xE0, 0x90, 0x8F, 0x8F, 0xF0, 0x22, 0x90, +0x8E, 0xCD, 0xE0, 0x30, 0xE0, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x06, 0x90, 0xE0, 0x20, 0xE5, 0x10, +0x90, 0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x09, 0x90, 0x01, 0xC7, 0x74, 0x25, 0xF0, 0x7F, 0x01, 0x22, +0x7F, 0x00, 0x22, 0x90, 0x02, 0x09, 0xE0, 0x90, 0x93, 0x4A, 0xF0, 0x12, 0x06, 0x89, 0x90, 0x93, +0x16, 0x12, 0x77, 0xC2, 0x90, 0x93, 0x17, 0xF0, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xFF, 0x12, 0x06, +0x89, 0xFE, 0xEF, 0x2E, 0x90, 0x93, 0x26, 0xF0, 0x22, 0xEF, 0x60, 0x08, 0x90, 0x93, 0x19, 0xE0, +0xFF, 0x12, 0x56, 0x98, 0x22, 0xE4, 0xFD, 0xFC, 0xEF, 0x60, 0x3C, 0x90, 0x93, 0x1C, 0x12, 0x67, +0x7A, 0x51, 0x21, 0x12, 0x7F, 0x3E, 0x90, 0x93, 0x4A, 0x12, 0x56, 0x7A, 0x75, 0x43, 0x40, 0x7B, +0x01, 0x7A, 0x8F, 0x79, 0x9A, 0x12, 0x35, 0x26, 0xE4, 0xFD, 0x7F, 0x03, 0x12, 0x30, 0xCE, 0x90, +0x93, 0x1D, 0xE0, 0x51, 0x18, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x12, 0x39, 0xD6, +0x7D, 0x01, 0x7F, 0x03, 0x12, 0x30, 0xCE, 0x22, 0x75, 0xF0, 0x80, 0xA4, 0xAE, 0xF0, 0x78, 0x03, +0x22, 0x74, 0x00, 0x2F, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0xEF, 0x60, 0x0A, 0x90, +0x06, 0x31, 0xE0, 0x44, 0x80, 0xF0, 0x12, 0x5B, 0x04, 0x22, 0xEF, 0x60, 0x06, 0x12, 0x66, 0x5B, +0x12, 0x57, 0x0C, 0x22, 0x90, 0x04, 0x1A, 0xE0, 0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x04, +0x1B, 0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x51, 0x44, 0xEF, +0x64, 0x01, 0x70, 0x47, 0x90, 0x8E, 0x19, 0xE0, 0xFF, 0x54, 0x03, 0x70, 0x3E, 0x90, 0x8E, 0x17, +0xE0, 0xFE, 0xE4, 0xC3, 0x9E, 0x40, 0x34, 0xEF, 0x20, 0xE2, 0x30, 0x90, 0x8E, 0x19, 0xE0, 0x20, +0xE4, 0x29, 0x90, 0x8E, 0x12, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x1E, 0x90, 0x8E, 0xBF, +0xE0, 0x70, 0x18, 0x90, 0x06, 0x62, 0xE0, 0x20, 0xE1, 0x11, 0x90, 0x06, 0x62, 0xE0, 0x30, 0xE0, +0x07, 0xE0, 0x54, 0xFC, 0x64, 0x80, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xEF, 0x24, +0xFE, 0x60, 0x0B, 0x04, 0x70, 0x24, 0x90, 0x8E, 0x1B, 0x74, 0x02, 0xF0, 0x80, 0x13, 0xED, 0x70, +0x06, 0x90, 0x8E, 0xBC, 0xE0, 0x80, 0x02, 0xED, 0x14, 0x90, 0x8E, 0x1B, 0xF0, 0x90, 0x8E, 0x1B, +0xE0, 0xA3, 0xF0, 0x90, 0x8E, 0x12, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x8E, 0xC0, 0xE0, 0xC3, +0x13, 0x20, 0xE0, 0x21, 0x90, 0x02, 0x87, 0xE0, 0x70, 0x24, 0x90, 0x8E, 0xC4, 0xE0, 0x30, 0xE0, +0x06, 0x90, 0x02, 0x82, 0xE0, 0x70, 0x17, 0x90, 0x8E, 0xCD, 0xE0, 0x20, 0xE0, 0x10, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE1, 0x09, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, -0x22, 0xEF, 0x60, 0x2E, 0x12, 0x6B, 0x46, 0x70, 0x29, 0x90, 0x8E, 0x81, 0xE0, 0x54, 0xFE, 0xF0, -0x7D, 0x2B, 0x7F, 0x0F, 0x12, 0x54, 0x51, 0x90, 0x06, 0x04, 0xE0, 0x54, 0xBF, 0xF0, 0x12, 0x57, -0x83, 0xBF, 0x01, 0x0E, 0x90, 0x8E, 0x80, 0xE0, 0x44, 0x40, 0xF0, 0x7D, 0x06, 0x7F, 0x01, 0x12, -0x53, 0xDC, 0x22, 0x7D, 0x2D, 0x12, 0x57, 0xF8, 0x90, 0x01, 0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, -0x03, 0x12, 0x6D, 0xA1, 0x12, 0x4B, 0x5A, 0xE4, 0xFD, 0x7F, 0x01, 0x02, 0x53, 0xDC, 0x7D, 0x2E, -0x7F, 0x6F, 0x12, 0x54, 0x51, 0x7D, 0x02, 0x7F, 0x01, 0x02, 0x53, 0xDC, 0x12, 0x57, 0xF3, 0x7D, -0x04, 0x7F, 0x01, 0x02, 0x53, 0xDC, 0x7D, 0x2F, 0x7F, 0xFF, 0x12, 0x54, 0x51, 0x12, 0x4B, 0x5A, -0x7D, 0x08, 0x7F, 0x01, 0x02, 0x53, 0xDC, 0x12, 0x6F, 0x13, 0x12, 0x57, 0xF3, 0x7D, 0x0C, 0x7F, -0x01, 0x02, 0x53, 0xDC, 0x90, 0x93, 0xB4, 0xED, 0xF0, 0x90, 0x93, 0xB2, 0xEE, 0xF0, 0xA3, 0xEF, -0xF0, 0x71, 0xB1, 0x90, 0x93, 0xB2, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x02, 0x7A, -0xFB, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x78, 0xE0, 0xFD, 0xB4, 0x02, 0x07, -0x91, 0x9C, 0x74, 0x08, 0xF0, 0x80, 0x09, 0xED, 0xB4, 0x04, 0x05, 0x91, 0x9C, 0x74, 0x10, 0xF0, -0xEF, 0x64, 0x02, 0x4E, 0x60, 0x02, 0x81, 0x97, 0x90, 0x90, 0x44, 0xE0, 0xFF, 0x64, 0xFE, 0x70, -0x02, 0x81, 0x97, 0xEF, 0x64, 0x02, 0x60, 0x07, 0xEF, 0x64, 0x03, 0x60, 0x02, 0x81, 0x97, 0x90, -0x90, 0xA4, 0x91, 0xA4, 0x90, 0x94, 0x07, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x7E, 0x00, 0x7F, 0x20, -0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xC5, 0x12, 0x08, 0xAA, 0x7E, 0x00, 0x7F, 0x20, 0x7D, -0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xE5, 0x12, 0x08, 0xAA, 0x90, 0xAC, 0x7A, 0x74, 0x10, 0x12, -0x59, 0xBE, 0x7B, 0x20, 0xFD, 0xFC, 0xFF, 0xFE, 0x12, 0x39, 0x9C, 0x7B, 0x01, 0x7A, 0x90, 0x79, -0xA6, 0x90, 0xAC, 0x89, 0x12, 0x44, 0x12, 0x7A, 0x93, 0x79, 0xE5, 0x90, 0xAC, 0x8C, 0x12, 0x44, -0x12, 0x90, 0xAC, 0x8F, 0x74, 0x20, 0xF0, 0x7A, 0x90, 0x79, 0x13, 0x12, 0x34, 0x5B, 0x75, 0x40, -0x01, 0x75, 0x41, 0x93, 0x75, 0x42, 0xED, 0x75, 0x43, 0x18, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0xC5, -0x12, 0x35, 0x26, 0x75, 0x40, 0x01, 0x75, 0x41, 0x93, 0x75, 0x42, 0xCD, 0x75, 0x43, 0x10, 0x7B, -0x01, 0x7A, 0x93, 0x79, 0xB5, 0x12, 0x35, 0x26, 0x90, 0x93, 0xCB, 0xE0, 0x54, 0x03, 0xFF, 0xC3, -0x94, 0x04, 0x90, 0x90, 0x01, 0x50, 0x04, 0xEF, 0xF0, 0x80, 0x03, 0x74, 0x05, 0xF0, 0x7B, 0x01, -0x7A, 0x93, 0x79, 0xB5, 0x12, 0x76, 0xDF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x94, 0x05, 0x74, -0x80, 0xF0, 0xA3, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFD, 0xED, 0xFF, 0x22, 0x7F, 0x50, 0x7E, 0x0C, -0x12, 0x37, 0x4E, 0x90, 0x94, 0xB5, 0xEF, 0xF0, 0x7F, 0x58, 0x7E, 0x0C, 0x12, 0x37, 0x4E, 0x90, -0x94, 0xB6, 0xEF, 0xF0, 0x90, 0x94, 0xFA, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, -0xFE, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x17, 0x7F, 0x50, 0x7E, 0x0C, 0x12, 0x4F, 0x38, 0x12, -0x08, 0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, 0xFE, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x17, -0x12, 0x4D, 0x8E, 0x90, 0x06, 0x08, 0xE0, 0x90, 0x94, 0xCB, 0xF0, 0x90, 0x06, 0xA1, 0xE0, 0xFE, -0x90, 0x06, 0xA0, 0x12, 0x61, 0x5C, 0x90, 0x94, 0xCD, 0xF0, 0xA3, 0xEF, 0xB1, 0x1F, 0xF0, 0x90, -0x06, 0xA0, 0x74, 0x20, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0xE4, 0xFD, 0xFF, 0x02, 0x4D, 0xF4, 0xF0, -0x90, 0x06, 0x08, 0xE0, 0x54, 0x7F, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, -0xB7, 0xE0, 0xFE, 0x90, 0x94, 0xB4, 0xE0, 0xC3, 0x9E, 0x40, 0x04, 0x7F, 0x00, 0x80, 0x0E, 0xEF, -0x60, 0x05, 0xD3, 0x94, 0x0E, 0x40, 0x04, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, -0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0xB8, 0xEF, 0xF0, 0x7D, 0x38, -0x7F, 0xFF, 0x12, 0x54, 0x51, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x13, 0x90, 0x06, 0x32, 0xE0, 0x44, -0x08, 0xF0, 0x90, 0x93, 0xB8, 0x12, 0x7A, 0x5E, 0x90, 0x93, 0xB9, 0x12, 0x57, 0xE7, 0x7D, 0x38, -0xE4, 0xFF, 0x12, 0x54, 0x51, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xED, 0x14, 0x60, 0x06, 0x04, 0x70, -0x03, 0x7F, 0x01, 0x22, 0x7F, 0x01, 0x22, 0x12, 0x97, 0xE1, 0x90, 0x90, 0xE3, 0xE0, 0x70, 0x02, -0xA3, 0xE0, 0x60, 0x2D, 0xE4, 0x90, 0x93, 0xAA, 0xF0, 0x90, 0x93, 0xAA, 0xE0, 0xFD, 0xC3, 0x94, -0x02, 0x50, 0x21, 0x12, 0x5D, 0xAA, 0xB1, 0xE5, 0xE0, 0x24, 0xF1, 0xF5, 0x82, 0xE4, 0x34, 0x90, -0xF5, 0x83, 0xE0, 0x6F, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x93, 0xAA, 0xE0, 0x04, 0xF0, 0x80, -0xD8, 0x7F, 0x00, 0x22, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x40, 0xF0, 0xE4, 0x90, 0x90, 0xEF, 0xF0, -0xA3, 0xF0, 0x7F, 0x01, 0x22, 0xED, 0x24, 0x1C, 0xFD, 0x12, 0x5C, 0xFE, 0x90, 0x93, 0xAA, 0x22, -0x12, 0x97, 0xE1, 0xE4, 0xA3, 0xF0, 0x90, 0x93, 0xAA, 0xE0, 0xFD, 0xC3, 0x94, 0x02, 0x50, 0x1B, -0x12, 0x5D, 0xAA, 0xB1, 0xE5, 0xE0, 0x24, 0x11, 0xF5, 0x82, 0xE4, 0x34, 0x91, 0xF5, 0x83, 0xE0, -0xB5, 0x07, 0x1D, 0x90, 0x93, 0xAA, 0xE0, 0x04, 0xF0, 0x80, 0xDB, 0x90, 0x06, 0x32, 0xE0, 0x44, -0x80, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0x30, 0xF0, 0x7F, 0x01, 0x12, 0x73, 0xCF, 0x7F, 0x01, 0x22, -0x7F, 0x00, 0x22, 0xD1, 0x6E, 0xE4, 0xA3, 0xF0, 0x90, 0x93, 0xA9, 0xE0, 0xFD, 0xC3, 0x94, 0x04, -0x50, 0x29, 0x90, 0x93, 0xA8, 0xE0, 0x24, 0x10, 0x12, 0x95, 0xE4, 0xFE, 0x12, 0x5C, 0xFE, 0x90, -0x93, 0xA9, 0xE0, 0x24, 0xE9, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE0, 0x6F, 0x60, 0x03, -0x7F, 0x00, 0x22, 0x90, 0x93, 0xA9, 0xE0, 0x04, 0xF0, 0x80, 0xCD, 0x7F, 0x01, 0x22, 0x90, 0x93, -0xA7, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xD1, 0x6E, 0x24, 0x16, 0xFF, 0xE4, 0x3E, 0x12, 0x5F, -0x1D, 0x90, 0x90, 0xED, 0xA3, 0xE0, 0xB5, 0x07, 0x1B, 0x90, 0x93, 0xA8, 0xE0, 0x24, 0x16, 0x12, -0x95, 0xE4, 0xFE, 0x7D, 0x01, 0x12, 0x5C, 0xFE, 0xEF, 0xFD, 0x90, 0x90, 0xED, 0xE0, 0x6D, 0x70, -0x01, 0xE4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x7F, 0x01, 0x22, 0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF, -0x54, 0xF7, 0x4E, 0xFF, 0xF0, 0x12, 0x06, 0x89, 0xFE, 0x22, 0x90, 0x8E, 0x81, 0xE0, 0x13, 0x13, -0x13, 0x54, 0x1F, 0x22, 0x90, 0x8F, 0x4B, 0xE0, 0xFF, 0x90, 0x8F, 0x4A, 0xE0, 0xFB, 0x90, 0x8F, -0x4C, 0xE0, 0x90, 0x95, 0x59, 0xF0, 0x22, 0x54, 0xFB, 0xF0, 0x90, 0x8E, 0x88, 0xE0, 0x54, 0xFD, -0xF0, 0x22, 0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x8F, 0x79, 0x53, 0x7E, 0x00, 0x7F, 0x04, 0x02, 0x45, -0xC7, 0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22, 0xE0, 0x7A, 0x00, 0x24, -0x00, 0xFF, 0xEA, 0x3E, 0x22, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x8D, 0xF8, 0xE0, 0x34, 0x00, 0x22, -0x90, 0x95, 0x0D, 0x12, 0x44, 0x12, 0xE4, 0x90, 0x95, 0x10, 0xF0, 0xA3, 0x22, 0x75, 0x40, 0x01, -0xF5, 0x41, 0x89, 0x42, 0x75, 0x43, 0x06, 0x7B, 0x01, 0x22, 0x75, 0xF0, 0x0F, 0xA4, 0x24, 0x60, -0xF9, 0x74, 0x8D, 0x35, 0xF0, 0x22, 0x7F, 0x48, 0x7E, 0x09, 0x12, 0x37, 0x4E, 0xE4, 0x22, 0x90, -0x93, 0xAA, 0xE0, 0xFD, 0x90, 0x93, 0xA9, 0xE0, 0x2D, 0x22, 0x74, 0x43, 0x2E, 0xF5, 0x82, 0xE4, -0x34, 0x91, 0xF5, 0x83, 0x22, 0x90, 0x93, 0x73, 0x12, 0x43, 0xF1, 0xD3, 0x02, 0x43, 0xD4, 0x90, -0x91, 0x3B, 0x12, 0x43, 0xE5, 0xEC, 0x4D, 0x4E, 0x4F, 0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x93, -0xAF, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x95, 0x2C, 0xE0, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x22, -0x7D, 0x01, 0x7E, 0x00, 0x7F, 0x10, 0x12, 0x45, 0xC7, 0xEF, 0x22, 0x7F, 0x84, 0x7E, 0x08, 0x12, -0x4D, 0x92, 0x90, 0x94, 0xE8, 0x22, 0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, -0xEF, 0xF0, 0xA3, 0x02, 0x44, 0x12, 0x90, 0x8E, 0x8A, 0xE0, 0x14, 0x90, 0x05, 0x73, 0xF0, 0x22, -0x4D, 0xFF, 0x90, 0x8F, 0x2E, 0xF0, 0xEE, 0x22, 0x90, 0x8D, 0xF8, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, -0x9F, 0xEE, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x91, 0xF5, 0x83, 0x22, -0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22, 0xE4, 0x90, 0x95, 0x4A, 0xF0, 0x7F, 0x04, 0x22, -0x7F, 0x01, 0x7E, 0x00, 0x02, 0x3D, 0xC2, 0xEF, 0x24, 0x01, 0xFF, 0xE4, 0x3E, 0xFE, 0x22, 0x90, -0x02, 0x86, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90, -0x8E, 0x81, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x90, 0x8E, 0x8A, 0xE0, 0xFF, 0xA3, 0xE0, 0x22, 0x90, -0x8E, 0x81, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90, 0x8E, 0x88, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x74, -0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22, 0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0xC3, 0x13, 0x22, 0xE0, -0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xFF, 0x22, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x22, 0x90, -0x93, 0xB7, 0xEE, 0xF0, 0xA3, 0xEF, 0x22, 0x12, 0x49, 0x39, 0x90, 0x95, 0x84, 0xE0, 0x22, 0x2F, -0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0x22, 0x00, 0x01, 0x93, +0x22, 0xEF, 0x60, 0x2E, 0x12, 0x73, 0x13, 0x70, 0x29, 0x90, 0x8E, 0x12, 0xE0, 0x54, 0xFE, 0xF0, +0x7D, 0x2B, 0x7F, 0x0F, 0x12, 0x53, 0xD9, 0x90, 0x06, 0x04, 0xE0, 0x54, 0xBF, 0xF0, 0x12, 0x65, +0x55, 0xBF, 0x01, 0x0E, 0x90, 0x8E, 0x11, 0xE0, 0x44, 0x40, 0xF0, 0x7D, 0x06, 0x7F, 0x01, 0x12, +0x4E, 0xB5, 0x22, 0x7D, 0x2D, 0x12, 0x8F, 0xCB, 0x90, 0x01, 0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, +0x03, 0x12, 0x75, 0x25, 0x12, 0x4B, 0x21, 0xE4, 0xFD, 0x7F, 0x01, 0x02, 0x4E, 0xB5, 0x7D, 0x2E, +0x7F, 0x6F, 0x12, 0x53, 0xD9, 0x7D, 0x02, 0x7F, 0x01, 0x02, 0x4E, 0xB5, 0x90, 0x95, 0x2E, 0xEF, +0xF0, 0x12, 0x4D, 0xE7, 0x90, 0x95, 0x2E, 0xE0, 0x60, 0x03, 0x12, 0x4F, 0xE9, 0x7D, 0x04, 0x7F, +0x01, 0x02, 0x4E, 0xB5, 0xE4, 0xF5, 0x58, 0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x58, 0x54, 0xC0, 0x70, +0x08, 0x71, 0xDD, 0x54, 0xFD, 0xF0, 0x02, 0x74, 0xB2, 0xE5, 0x58, 0x30, 0xE6, 0x1F, 0x90, 0x8E, +0x15, 0xE0, 0x64, 0x01, 0x70, 0x19, 0x90, 0x8E, 0x19, 0xE0, 0x44, 0x01, 0xF0, 0x12, 0x77, 0xF5, +0x64, 0x02, 0x60, 0x04, 0x71, 0xEF, 0x80, 0x07, 0x12, 0x67, 0x84, 0x80, 0x02, 0x71, 0xDD, 0xE5, +0x58, 0x90, 0x8E, 0x19, 0x30, 0xE7, 0x11, 0xE0, 0x44, 0x02, 0xF0, 0x71, 0xE5, 0x12, 0x50, 0x0D, +0x90, 0x8E, 0x11, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x8E, 0x19, +0xE0, 0x54, 0xFE, 0xF0, 0x22, 0xE4, 0x90, 0x94, 0xE2, 0xF0, 0x90, 0x8E, 0xBA, 0xE0, 0x22, 0x90, +0x04, 0x1D, 0xE0, 0x70, 0x12, 0x90, 0x8D, 0x08, 0xE0, 0xFF, 0x7B, 0x18, 0xE4, 0xFD, 0x12, 0x64, +0x38, 0x90, 0x95, 0x24, 0x12, 0x57, 0xFC, 0x22, 0xE4, 0xFD, 0xF9, 0xFC, 0x90, 0x05, 0x62, 0xE0, +0xFE, 0x90, 0x05, 0x61, 0xE0, 0xFB, 0xEB, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, +0xFF, 0xEE, 0x54, 0x3F, 0x90, 0x8E, 0x4E, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, +0xFF, 0x90, 0x8E, 0x4E, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xC3, 0x9F, 0xEA, 0x9E, 0x40, 0x21, 0xEB, +0x9F, 0xFF, 0x90, 0x8E, 0x2D, 0xE0, 0xFE, 0xC3, 0x74, 0x0A, 0x9E, 0x2F, 0xF9, 0xC3, 0x94, 0x19, +0x50, 0x0E, 0x74, 0x32, 0x29, 0x91, 0xF5, 0xE0, 0x04, 0xF0, 0x90, 0x8E, 0x2B, 0xE0, 0x04, 0xF0, +0x90, 0x8E, 0x2B, 0xE0, 0xC3, 0x94, 0x64, 0x50, 0x02, 0x81, 0xF1, 0xE4, 0xFC, 0xFD, 0x91, 0xF2, +0xE0, 0x2C, 0xFC, 0xD3, 0x94, 0x05, 0x40, 0x07, 0x90, 0x93, 0xFA, 0xED, 0xF0, 0x80, 0x05, 0x0D, +0xED, 0xB4, 0x19, 0xEA, 0xE4, 0xFC, 0xFD, 0x91, 0xF2, 0xE0, 0x2C, 0xFC, 0xD3, 0x94, 0x5F, 0x40, +0x07, 0x90, 0x93, 0xFB, 0xED, 0xF0, 0x80, 0x05, 0x0D, 0xED, 0xB4, 0x19, 0xEA, 0x90, 0x93, 0xFA, +0xE0, 0x90, 0x8E, 0x30, 0xF0, 0x90, 0x93, 0xFB, 0xE0, 0x90, 0x8E, 0x31, 0x91, 0xFD, 0x94, 0x0B, +0x40, 0x0A, 0xEF, 0x24, 0xF6, 0x90, 0x8E, 0x28, 0xF0, 0xE4, 0x80, 0x09, 0xE4, 0x90, 0x8E, 0x28, +0x91, 0xFD, 0x74, 0x0A, 0x9F, 0x90, 0x8E, 0x27, 0xF0, 0x90, 0x8E, 0x30, 0xE0, 0xFF, 0xA3, 0xE0, +0xC3, 0x9F, 0x90, 0x8E, 0x2E, 0xF0, 0xC3, 0x94, 0x08, 0x50, 0x03, 0x74, 0x08, 0xF0, 0x90, 0x8E, +0x28, 0xE0, 0xFD, 0x90, 0x8E, 0x2E, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x8E, 0xB0, 0xE4, 0xFF, 0xB1, +0x05, 0x22, 0x74, 0x32, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8E, 0xF5, 0x83, 0x22, 0xF0, 0x90, 0x8E, +0x30, 0xE0, 0xFF, 0xC3, 0x22, 0xE4, 0xFE, 0x74, 0x32, 0x2E, 0x91, 0xF5, 0xE4, 0xF0, 0x0E, 0xEE, +0xB4, 0x19, 0xF4, 0xE4, 0x90, 0x8E, 0x2B, 0xF0, 0x90, 0x8E, 0x2F, 0xF0, 0x90, 0x8E, 0x27, 0xF0, +0xEF, 0xB4, 0x01, 0x09, 0x90, 0x8E, 0x30, 0x74, 0x19, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x7D, 0x2F, +0x12, 0x4B, 0x1C, 0x7D, 0x08, 0x7F, 0x01, 0x02, 0x4E, 0xB5, 0x90, 0x93, 0x53, 0xED, 0xF0, 0x90, +0x93, 0x51, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xB1, 0x57, 0x90, 0x93, 0x51, 0xE0, 0xFE, 0xA3, 0xE0, +0xFF, 0xA3, 0xE0, 0xFD, 0x02, 0x58, 0x08, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, +0x17, 0xE0, 0xFD, 0xB4, 0x02, 0x07, 0xD1, 0x36, 0x74, 0x08, 0xF0, 0x80, 0x09, 0xED, 0xB4, 0x04, +0x05, 0xD1, 0x36, 0x74, 0x10, 0xF0, 0xEF, 0x64, 0x02, 0x4E, 0x60, 0x02, 0xC1, 0x31, 0x90, 0x8F, +0xDB, 0xE0, 0xFF, 0x64, 0xFE, 0x70, 0x02, 0xC1, 0x31, 0xEF, 0x64, 0x02, 0x60, 0x07, 0xEF, 0x64, +0x03, 0x60, 0x02, 0xC1, 0x31, 0x90, 0x90, 0x3B, 0xD1, 0x47, 0x90, 0x93, 0xA6, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0xD1, 0x3E, 0x7A, 0x93, 0x79, 0x64, 0x12, 0x08, 0xAA, 0xD1, 0x3E, 0x7A, 0x93, 0x79, +0x84, 0x12, 0x08, 0xAA, 0x90, 0xAC, 0x7A, 0x74, 0x10, 0x12, 0x67, 0xE6, 0x7B, 0x20, 0xFD, 0xFC, +0xFF, 0xFE, 0x12, 0x39, 0x9C, 0x7B, 0x01, 0x7A, 0x90, 0x79, 0x3D, 0x90, 0xAC, 0x89, 0x12, 0x44, +0x12, 0x7A, 0x93, 0x79, 0x84, 0x90, 0xAC, 0x8C, 0x12, 0x44, 0x12, 0x90, 0xAC, 0x8F, 0x74, 0x20, +0xF0, 0x7A, 0x8F, 0x79, 0xAA, 0x12, 0x34, 0x5B, 0x75, 0x40, 0x01, 0x75, 0x41, 0x93, 0x75, 0x42, +0x8C, 0x75, 0x43, 0x18, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x64, 0x12, 0x35, 0x26, 0x75, 0x40, 0x01, +0x75, 0x41, 0x93, 0x75, 0x42, 0x6C, 0x75, 0x43, 0x10, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x54, 0x12, +0x35, 0x26, 0x90, 0x93, 0x6A, 0xE0, 0x54, 0x03, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x8F, 0x98, 0x50, +0x04, 0xEF, 0xF0, 0x80, 0x03, 0x74, 0x05, 0xF0, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x54, 0x12, 0x7E, +0x67, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x93, 0xA4, 0x74, 0x80, 0xF0, 0xA3, 0x22, 0x7E, 0x00, +0x7F, 0x20, 0x7D, 0x00, 0x7B, 0x01, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFD, 0xED, 0xFF, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12, 0x7F, 0x59, 0x90, 0x8D, +0xFB, 0x12, 0x7A, 0xF3, 0x54, 0x04, 0xFC, 0xEF, 0x54, 0xFB, 0x4C, 0xFF, 0x90, 0x8D, 0xFB, 0xD1, +0xF1, 0x12, 0x77, 0xC2, 0xFF, 0xED, 0x2F, 0x90, 0x8D, 0xFC, 0x12, 0x7D, 0xB3, 0xFF, 0xAE, 0x05, +0xED, 0x2F, 0x90, 0x8D, 0xFD, 0xF0, 0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0x20, 0xE0, 0x08, 0x13, 0x13, +0x13, 0x54, 0x1F, 0x30, 0xE0, 0x0A, 0x90, 0x06, 0x31, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x66, 0xEF, +0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0x30, 0xE0, 0x33, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x01, 0xF0, 0x90, +0x06, 0x09, 0xE0, 0x54, 0xFE, 0xD1, 0xE8, 0xEF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x08, 0xD1, +0xE0, 0x90, 0x94, 0x6E, 0x74, 0x01, 0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x75, 0x25, 0x90, 0x94, +0xE5, 0x12, 0x08, 0x79, 0x00, 0x00, 0x27, 0x10, 0x12, 0x50, 0x45, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x90, 0x02, 0x86, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xF0, 0x90, 0x06, 0x08, 0xE0, 0x54, 0x7F, 0xF0, +0x22, 0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x4E, 0x22, 0x7F, 0x50, 0x7E, 0x0C, 0x12, +0x37, 0x4E, 0x90, 0x94, 0x54, 0xEF, 0xF0, 0x7F, 0x58, 0x7E, 0x0C, 0x12, 0x37, 0x4E, 0x90, 0x94, +0x55, 0xEF, 0xF0, 0x90, 0x94, 0x99, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, 0x9D, +0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x17, 0x7F, 0x50, 0x7E, 0x0C, 0x12, 0x5F, 0x34, 0x12, 0x08, +0x79, 0x00, 0x00, 0x00, 0x7F, 0x90, 0x94, 0x9D, 0x12, 0x08, 0x79, 0x00, 0x00, 0x00, 0x17, 0x12, +0x5E, 0xCA, 0x90, 0x06, 0x08, 0xE0, 0x90, 0x94, 0x6A, 0xF0, 0x90, 0x06, 0xA1, 0xE0, 0xFE, 0x90, +0x06, 0xA0, 0x12, 0x84, 0xA3, 0x90, 0x94, 0x6C, 0xF0, 0xA3, 0xEF, 0xD1, 0xE8, 0x90, 0x06, 0xA0, +0x74, 0x20, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0xE4, 0xFD, 0xFF, 0x02, 0x5D, 0x92, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x58, 0xEF, 0xF0, 0x12, 0x57, 0xCE, 0x74, 0x10, 0x2F, 0xFF, +0x90, 0x93, 0x58, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0x2F, 0xFF, 0x12, 0x56, 0xFE, 0x75, 0x43, 0x04, +0x7B, 0x01, 0x7A, 0x94, 0x79, 0x66, 0x12, 0x35, 0x26, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x94, 0x56, 0xE0, 0xFE, 0x90, 0x94, 0x53, 0xE0, 0xC3, 0x9E, +0x40, 0x04, 0x7F, 0x00, 0x80, 0x0E, 0xEF, 0x60, 0x05, 0xD3, 0x94, 0x0E, 0x40, 0x04, 0x7F, 0x00, +0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8E, 0xC4, 0xF1, 0xD5, 0x30, 0xE0, +0x03, 0x12, 0x4E, 0x87, 0x22, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22, 0x90, 0x93, 0x70, +0xE4, 0x75, 0xF0, 0x08, 0x12, 0x08, 0xD6, 0x90, 0x93, 0x70, 0xE4, 0x75, 0xF0, 0x08, 0x02, 0x08, +0xD6, 0xA3, 0xE0, 0x24, 0x28, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0x24, 0x48, 0xF9, +0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22, 0x90, 0x93, 0x6D, 0xE0, 0xFF, 0x24, 0xE3, 0xF5, 0x82, +0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0x22, 0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x8E, 0x79, 0xEA, 0x7E, +0x00, 0x7F, 0x04, 0x02, 0x45, 0xC7, 0x90, 0x8E, 0x4B, 0xE0, 0x24, 0x04, 0x90, 0x8E, 0x2D, 0xF0, +0xA3, 0x74, 0x08, 0xF0, 0x22, 0xE0, 0x7A, 0x00, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x22, 0x90, 0x93, +0x6B, 0xEF, 0xF0, 0x90, 0x93, 0x1B, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x22, 0xF5, 0x83, 0xEF, 0xF0, +0x90, 0x93, 0x4E, 0xE0, 0x04, 0xF0, 0x22, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x8D, 0xF8, 0xE0, 0x34, +0x00, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12, 0x06, 0x89, 0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x22, +0x90, 0x8E, 0x11, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22, 0x90, 0x94, 0xAC, 0x12, 0x44, 0x12, +0xE4, 0x90, 0x94, 0xAF, 0xF0, 0xA3, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x40, 0xF0, 0xE0, 0x44, +0x80, 0xF0, 0x22, 0x90, 0x8E, 0xB9, 0xE0, 0xFF, 0x90, 0x8E, 0x1E, 0xE0, 0xD3, 0x9F, 0x22, 0xFF, +0xEE, 0x54, 0x3F, 0x90, 0x8E, 0x50, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x93, 0x49, 0xE0, 0xFD, +0x90, 0x93, 0x48, 0xE0, 0x2D, 0x22, 0x90, 0x93, 0x70, 0xE4, 0x75, 0xF0, 0x02, 0x02, 0x08, 0xD6, +0xF0, 0x90, 0x8E, 0x21, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0x24, 0x30, 0xF9, 0xE4, 0x34, +0xFC, 0xFA, 0x7B, 0x01, 0x22, 0x75, 0x41, 0x8F, 0x75, 0x42, 0xE1, 0x75, 0x43, 0x02, 0x22, 0xF0, +0xEE, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F, 0x4E, 0x22, 0xF0, 0xEE, 0x54, 0x20, 0xFE, 0xEF, 0x54, +0xDF, 0x4E, 0x22, 0x90, 0x93, 0xF8, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x93, 0x6D, 0xE0, +0xFF, 0xC3, 0x94, 0x10, 0x22, 0x90, 0x93, 0x4C, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x01, +0x1F, 0xE0, 0xFE, 0x90, 0x01, 0x1E, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0x22, +0x90, 0x94, 0xF8, 0xE0, 0x7F, 0x48, 0x7E, 0x09, 0x22, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, +0x22, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x7F, 0x01, 0x7E, 0x00, 0x02, 0x3D, 0xC2, +0xEF, 0x24, 0x01, 0xFF, 0xE4, 0x3E, 0xFE, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x54, 0xFB, 0xF0, 0x22, +0x90, 0x93, 0xF7, 0xE0, 0xC3, 0x94, 0x0A, 0x22, 0xF0, 0xE4, 0x90, 0x93, 0x7B, 0xF0, 0xA3, 0x22, +0xEA, 0x90, 0xFD, 0x11, 0xF0, 0xAF, 0x03, 0x22, 0x90, 0x8E, 0x1B, 0xE0, 0x90, 0x05, 0x73, 0x22, +0x90, 0x8E, 0x12, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90, 0x8E, 0x19, 0xE0, 0x44, 0x10, 0xF0, 0x22, +0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x8D, 0xFB, 0xE0, 0xFF, 0xC3, 0x13, 0x22, +0x12, 0x08, 0xD6, 0x90, 0x8D, 0xF8, 0xE0, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xFF, 0x22, +0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0x22, 0x54, 0xDC }; -u4Byte ArrayLength_MP_8723B_FW_WoWLAN = 24698; +u4Byte ArrayLength_MP_8723B_FW_WoWLAN = 25034; void diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MAC.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MAC.c index 98068e6b201b..74c100e9f931 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MAC.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MAC.c @@ -18,8 +18,8 @@ * ******************************************************************************/ - -#include "../odm_precomp.h" +#include "Mp_Precomp.h" +#include "../phydm_precomp.h" #if (RTL8723B_SUPPORT == 1) static BOOLEAN @@ -224,72 +224,69 @@ ODM_ReadAndConfig_MP_8723B_MAC_REG( ) { u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; +//ask by Luke.Lee u4Byte ArrayLen = sizeof(Array_MP_8723B_MAC_REG)/sizeof(u4Byte); pu4Byte Array = Array_MP_8723B_MAC_REG; ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8723B_MAC_REG\n")); - for (i = 0; i < ArrayLen; i += 2 ) - { - u4Byte v1 = Array[i]; - u4Byte v2 = Array[i+1]; - - // This (offset, data) pair doesn't care the condition. - if ( v1 < 0x40000000 ) - { - odm_ConfigMAC_8723B(pDM_Odm, v1, (u1Byte)v2); - continue; - } - else - { // This line is the beginning of branch. - BOOLEAN bMatched = TRUE; - u1Byte cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - - if (cCond == COND_ELSE) { // ELSE, ENDIF - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } else if ( ! CheckPositive(pDM_Odm, v1, v2) ) { - bMatched = FALSE; - READ_NEXT_PAIR(v1, v2, i); - READ_NEXT_PAIR(v1, v2, i); - } else { - READ_NEXT_PAIR(v1, v2, i); - if ( ! CheckNegative(pDM_Odm, v1, v2) ) - bMatched = FALSE; - else - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } + while(( i+1) < ArrayLen) + { + u4Byte v1 = Array[i]; + u4Byte v2 = Array[i+1]; - if ( bMatched == FALSE ) - { // Condition isn't matched. Discard the following (offset, data) pairs. - while (v1 < 0x40000000 && i < ArrayLen -2) - READ_NEXT_PAIR(v1, v2, i); - - i -= 2; // prevent from for-loop += 2 - } - else // Configure matched pairs and skip to end of if-else. - { - while (v1 < 0x40000000 && i < ArrayLen-2) { - odm_ConfigMAC_8723B(pDM_Odm, v1, (u1Byte)v2); - READ_NEXT_PAIR(v1, v2, i); - } - - // Keeps reading until ENDIF. - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - while (cCond != COND_ENDIF && i < ArrayLen-2) { - READ_NEXT_PAIR(v1, v2, i); - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - } - } - } - } + if(v1 & (BIT31|BIT30)) //positive & negative condition + { + if(v1 & BIT31) // positive condition + { + cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); + if(cCond == COND_ENDIF) //end + { + bMatched = TRUE; + bSkipped = FALSE; + } + else if(cCond == COND_ELSE) //else + { + bMatched = bSkipped?FALSE:TRUE; + } + else //if , else if + { + if(bSkipped) + bMatched = FALSE; + else + { + if(CheckPositive(pDM_Odm, v1, v2)) + { + bMatched = TRUE; + bSkipped = TRUE; + } + else + { + bMatched = FALSE; + bSkipped = FALSE; + } + } + } + } + else if(v1 & BIT30){ //negative condition + //do nothing + } + } + else + { + if(bMatched) + odm_ConfigMAC_8723B(pDM_Odm, v1, (u1Byte)v2); + } + i = i + 2; + } } u4Byte ODM_GetVersion_MP_8723B_MAC_REG(void) { - return 11; + return 12; } #endif // end of HWIMG_SUPPORT diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MP.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MP.c index 494cc887f7c3..24f19fc835ad 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MP.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_MP.c @@ -18,7 +18,7 @@ * ******************************************************************************/ -#include "../odm_precomp.h" +#include "../phydm_precomp.h" #if (RTL8723B_SUPPORT==1) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_RF.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_RF.c index a7d6e5156d70..e4480ccf56be 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_RF.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalHWImg8723B_RF.c @@ -18,8 +18,8 @@ * ******************************************************************************/ - -#include "../odm_precomp.h" +#include "Mp_Precomp.h" +#include "../phydm_precomp.h" #if (RTL8723B_SUPPORT == 1) static BOOLEAN @@ -245,72 +245,69 @@ ODM_ReadAndConfig_MP_8723B_RadioA( ) { u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; +//ask by Luke.Lee u4Byte ArrayLen = sizeof(Array_MP_8723B_RadioA)/sizeof(u4Byte); pu4Byte Array = Array_MP_8723B_RadioA; ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8723B_RadioA\n")); - for (i = 0; i < ArrayLen; i += 2 ) - { - u4Byte v1 = Array[i]; - u4Byte v2 = Array[i+1]; - - // This (offset, data) pair doesn't care the condition. - if ( v1 < 0x40000000 ) - { - odm_ConfigRF_RadioA_8723B(pDM_Odm, v1, v2); - continue; - } - else - { // This line is the beginning of branch. - BOOLEAN bMatched = TRUE; - u1Byte cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - - if (cCond == COND_ELSE) { // ELSE, ENDIF - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } else if ( ! CheckPositive(pDM_Odm, v1, v2) ) { - bMatched = FALSE; - READ_NEXT_PAIR(v1, v2, i); - READ_NEXT_PAIR(v1, v2, i); - } else { - READ_NEXT_PAIR(v1, v2, i); - if ( ! CheckNegative(pDM_Odm, v1, v2) ) - bMatched = FALSE; - else - bMatched = TRUE; - READ_NEXT_PAIR(v1, v2, i); - } - - if ( bMatched == FALSE ) - { // Condition isn't matched. Discard the following (offset, data) pairs. - while (v1 < 0x40000000 && i < ArrayLen -2) - READ_NEXT_PAIR(v1, v2, i); - - i -= 2; // prevent from for-loop += 2 - } - else // Configure matched pairs and skip to end of if-else. - { - while (v1 < 0x40000000 && i < ArrayLen-2) { - odm_ConfigRF_RadioA_8723B(pDM_Odm, v1, v2); - READ_NEXT_PAIR(v1, v2, i); - } - - // Keeps reading until ENDIF. - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - while (cCond != COND_ENDIF && i < ArrayLen-2) { - READ_NEXT_PAIR(v1, v2, i); - cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); - } - } - } - } + while(( i+1) < ArrayLen) + { + u4Byte v1 = Array[i]; + u4Byte v2 = Array[i+1]; + + if(v1 & (BIT31|BIT30)) //positive & negative condition + { + if(v1 & BIT31) // positive condition + { + cCond = (u1Byte)((v1 & (BIT29|BIT28)) >> 28); + if(cCond == COND_ENDIF) //end + { + bMatched = TRUE; + bSkipped = FALSE; + } + else if(cCond == COND_ELSE) //else + { + bMatched = bSkipped?FALSE:TRUE; + } + else //if , else if + { + if(bSkipped) + bMatched = FALSE; + else + { + if(CheckPositive(pDM_Odm, v1, v2)) + { + bMatched = TRUE; + bSkipped = TRUE; + } + else + { + bMatched = FALSE; + bSkipped = FALSE; + } + } + } + } + else if(v1 & BIT30){ //negative condition + //do nothing + } + } + else + { + if(bMatched) + odm_ConfigRF_RadioA_8723B(pDM_Odm, v1, v2); + } + i = i + 2; + } } u4Byte ODM_GetVersion_MP_8723B_RadioA(void) { - return 11; + return 12; } /****************************************************************************** diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalPhyRf_8723B.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalPhyRf_8723B.c index 4788c3109152..0cbf190188cd 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalPhyRf_8723B.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/HalPhyRf_8723B.c @@ -18,7 +18,8 @@ * ******************************************************************************/ -#include "../odm_precomp.h" +#include "Mp_Precomp.h" +#include "../phydm_precomp.h" @@ -65,8 +66,6 @@ void setIqkMatrix_8723B( if (OFDM_index >= OFDM_TABLE_SIZE) OFDM_index = OFDM_TABLE_SIZE-1; - else if (OFDM_index < 0) - OFDM_index = 0; ele_D = (OFDMSwingTable_New[OFDM_index] & 0xFFC00000)>>22; @@ -251,8 +250,7 @@ ODM_TxPwrTrackSetPwr_8723B( u1Byte Final_CCK_Swing_Index = 0; u1Byte i = 0; -#if (MP_DRIVER==1) - if ( *(pDM_Odm->mp_mode) == 1) + if (pDM_Odm->mp_mode == TRUE) { #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE )) #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) @@ -264,7 +262,6 @@ ODM_TxPwrTrackSetPwr_8723B( #endif } else -#endif { u2Byte rate = *(pDM_Odm->pForcedDataRate); @@ -320,8 +317,8 @@ ODM_TxPwrTrackSetPwr_8723B( pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = pDM_Odm->Absolute_OFDMSwingIdx[RFPath]; #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE )) - #if (MP_DRIVER == 1) - if ( *(pDM_Odm->mp_mode) == 1) { + if (pDM_Odm->mp_mode == TRUE) + { pwr = PHY_QueryBBReg(Adapter, rTxAGC_A_Rate18_06, 0xFF); pwr += pDM_Odm->RFCalibrateInfo.PowerIndexOffset[RFPath]; PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, pwr); @@ -341,7 +338,6 @@ ODM_TxPwrTrackSetPwr_8723B( ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("ODM_TxPwrTrackSetPwr8723B: OFDM Tx-rf(A) Power = 0x%x\n", TxAGC)); } else - #endif { pDM_Odm->Modify_TxAGC_Flag_PathA = TRUE; pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = TRUE; @@ -661,21 +657,12 @@ phy_PathA_IQK_8723B( ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xe98, bMaskDWord))); - //Allen 20131125 - tmp=(regE9C & 0x03FF0000)>>16; - if ((tmp & 0x200)> 0) - tmp = 0x400 - tmp; - if(!(regEAC & BIT28) && (((regE94 & 0x03FF0000)>>16) != 0x142) && - (((regE9C & 0x03FF0000)>>16) != 0x42) && - (((regE94 & 0x03FF0000)>>16) <0x110) && - (((regE94 & 0x03FF0000)>>16) >0xf0) && - (tmp <0xf)) - + (((regE9C & 0x03FF0000)>>16) != 0x42)) result |= 0x01; - else //if Tx not OK, ignore Rx - return result; + + return result; #if 0 if(!(regEAC & BIT27) && //if Tx is OK, check whether Rx is OK @@ -685,10 +672,6 @@ phy_PathA_IQK_8723B( else RT_DISP(FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n")); #endif - - return result; - - } u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK @@ -795,17 +778,9 @@ phy_PathA_RxIQK8723B( ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n", ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xe98, bMaskDWord))); - //Allen 20131125 - tmp=(regE9C & 0x03FF0000)>>16; - if ((tmp & 0x200)> 0) - tmp = 0x400 - tmp; - if(!(regEAC & BIT28) && (((regE94 & 0x03FF0000)>>16) != 0x142) && - (((regE9C & 0x03FF0000)>>16) != 0x42) && - (((regE94 & 0x03FF0000)>>16) <0x110) && - (((regE94 & 0x03FF0000)>>16) >0xf0) && - (tmp <0xf)) + (((regE9C & 0x03FF0000)>>16) != 0x42)) result |= 0x01; else //if Tx not OK, ignore Rx @@ -900,16 +875,7 @@ phy_PathA_RxIQK8723B( ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x780 ); -#if 0 - if(!(regEAC & BIT28) && - (((regE94 & 0x03FF0000)>>16) != 0x142) && - (((regE9C & 0x03FF0000)>>16) != 0x42) ) - result |= 0x01; - else //if Tx not OK, ignore Rx - return result; -#endif - - //Allen 20131125 + /* Allen 20141201 */ tmp=(regEAC & 0x03FF0000)>>16; if ((tmp & 0x200)> 0) tmp = 0x400 - tmp; @@ -917,9 +883,9 @@ phy_PathA_RxIQK8723B( if(!(regEAC & BIT27) && //if Tx is OK, check whether Rx is OK (((regEA4 & 0x03FF0000)>>16) != 0x132) && (((regEAC & 0x03FF0000)>>16) != 0x36)&& - (((regEA4 & 0x03FF0000)>>16) < 0x110) && - (((regEA4 & 0x03FF0000)>>16) > 0xf0) && - (tmp <0xf)) + (((regEA4 & 0x03FF0000)>>16) < 0x11a) && + (((regEA4 & 0x03FF0000)>>16) > 0xe6) && + (tmp < 0x1a)) result |= 0x02; else //if Tx not OK, ignore Rx ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK fail!!\n")); @@ -1031,20 +997,12 @@ phy_PathB_IQK_8723B( ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n", ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xe98, bMaskDWord))); - //Allen 20131125 - tmp=(regE9C & 0x03FF0000)>>16; - if ((tmp & 0x200)> 0) - tmp = 0x400 - tmp; - if(!(regEAC & BIT28) && (((regE94 & 0x03FF0000)>>16) != 0x142) && - (((regE9C & 0x03FF0000)>>16) != 0x42)&& - (((regE94 & 0x03FF0000)>>16) <0x110) && - (((regE94 & 0x03FF0000)>>16) >0xf0) && - (tmp <0xf)) + (((regE9C & 0x03FF0000)>>16) != 0x42)) result |= 0x01; - else - return result; + + return result; #if 0 if(!(regEAC & BIT30) && @@ -1055,7 +1013,6 @@ phy_PathB_IQK_8723B( ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n")); #endif - return result; } @@ -1164,19 +1121,10 @@ phy_PathB_RxIQK8723B( ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n", ODM_GetBBReg(pDM_Odm, 0xe90, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xe98, bMaskDWord))); - //Allen 20131125 - tmp=(regE9C & 0x03FF0000)>>16; -// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("tmp1 = 0x%x\n", tmp)); - if ((tmp & 0x200)> 0) - tmp = 0x400 - tmp; -// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("tmp2 = 0x%x\n", tmp)); if(!(regEAC & BIT28) && (((regE94 & 0x03FF0000)>>16) != 0x142) && - (((regE9C & 0x03FF0000)>>16) != 0x42) && - (((regE94 & 0x03FF0000)>>16) <0x110) && - (((regE94 & 0x03FF0000)>>16) >0xf0) && - (tmp <0xf)) + (((regE9C & 0x03FF0000)>>16) != 0x42)) result |= 0x01; else //if Tx not OK, ignore Rx return result; @@ -1284,7 +1232,7 @@ phy_PathB_RxIQK8723B( #endif - //Allen 20131125 + /* Allen 20141201 */ tmp=(regEAC & 0x03FF0000)>>16; if ((tmp & 0x200)> 0) tmp = 0x400 - tmp; @@ -1292,9 +1240,9 @@ phy_PathB_RxIQK8723B( if(!(regEAC & BIT27) && //if Tx is OK, check whether Rx is OK (((regEA4 & 0x03FF0000)>>16) != 0x132) && (((regEAC & 0x03FF0000)>>16) != 0x36) && - (((regEA4 & 0x03FF0000)>>16) <0x110) && - (((regEA4 & 0x03FF0000)>>16) >0xf0) && - (tmp <0xf)) + (((regEA4 & 0x03FF0000)>>16) < 0x11a) && + (((regEA4 & 0x03FF0000)>>16) > 0xe6) && + (tmp < 0x1a)) result |= 0x02; else @@ -3026,13 +2974,13 @@ PHY_IQCalibrate_8723B( //#define PATH_S0 1 // RF_PATH_B //#define PATH_S1 0 // RF_PATH_A - path = (ODM_GetBBReg(pDM_Odm,rS0S1_PathSwitch,bMaskByte0)==0x00) ? ODM_RF_PATH_A : ODM_RF_PATH_B; + path = (RF_Path==0 ? ODM_RF_PATH_A : ODM_RF_PATH_B); // Restore TX IQK for (i = 0; i < 3; ++i) { offset = pRFCalibrateInfo->TxIQC_8723B[path][i][0]; data = pRFCalibrateInfo->TxIQC_8723B[path][i][1]; - if ((offset==0) || (data==0)) { + if ((offset==0) || (i==1 && data==0)) { // 0xc80, 0xc88 ==> index=1 DBG_871X("%s =>path:%s Restore TX IQK result failed \n",__FUNCTION__,(path==ODM_RF_PATH_A)?"A":"B"); bResult = FAIL; break; @@ -3045,7 +2993,7 @@ PHY_IQCalibrate_8723B( for (i = 0; i < 2; ++i) { offset = pRFCalibrateInfo->RxIQC_8723B[path][i][0]; data = pRFCalibrateInfo->RxIQC_8723B[path][i][1]; - if ((offset==0) || (data==0)) { + if ((offset==0) || (i==0 && data==0)) { // 0xc14, 0xc1c ==> index=0 DBG_871X("%s =>path:%s Restore RX IQK result failed \n",__FUNCTION__,(path==ODM_RF_PATH_A)?"A":"B"); bResult = FAIL; break; @@ -3063,7 +3011,7 @@ PHY_IQCalibrate_8723B( } if (bResult == SUCCESS) - return; + goto out; } #if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_AP)) @@ -3078,8 +3026,9 @@ PHY_IQCalibrate_8723B( #else _PHY_ReloadADDARegisters8723B(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); #endif - return; + goto out; } + StartTime = ODM_GetCurrentTime( pDM_Odm); ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:Start!!!\n")); @@ -3206,7 +3155,7 @@ PHY_IQCalibrate_8723B( } #if MP_DRIVER == 1 - if ((pMptCtx->MptRfPath == ODM_RF_PATH_A) || ( *(pDM_Odm->mp_mode) == 0)) + if ((pMptCtx->MptRfPath == ODM_RF_PATH_A) || (pDM_Odm->mp_mode == FALSE)) #endif { if (RegE94 != 0) @@ -3221,7 +3170,7 @@ PHY_IQCalibrate_8723B( #if !(DM_ODM_SUPPORT_TYPE & ODM_AP) #if MP_DRIVER == 1 - if ((pMptCtx->MptRfPath == ODM_RF_PATH_A) || ( *(pDM_Odm->mp_mode) == 0)) + if ((pMptCtx->MptRfPath == ODM_RF_PATH_A) || (pDM_Odm->mp_mode == FALSE)) #endif { if (RegEB4 != 0) @@ -3279,15 +3228,14 @@ PHY_IQCalibrate_8723B( ODM_SetIQCbyRFpath(pDM_Odm, 1); } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK finished\n")); + ProgressingTime = ODM_GetProgressingTime( pDM_Odm, StartTime); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK ProgressingTime = %d\n", ProgressingTime)); + +out: ODM_AcquireSpinLock(pDM_Odm, RT_IQK_SPINLOCK); pDM_Odm->RFCalibrateInfo.bIQKInProgress = FALSE; ODM_ReleaseSpinLock(pDM_Odm, RT_IQK_SPINLOCK); - - ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK finished\n")); - ProgressingTime = ODM_GetProgressingTime( pDM_Odm, StartTime); - ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK ProgressingTime = %d\n", ProgressingTime)); - - } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/Mp_Precomp.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/Mp_Precomp.h new file mode 100755 index 000000000000..43ea006e752b --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/Mp_Precomp.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//#include +//#include "phydm_precomp.h" +//#include "../phydm_precomp.h" + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RTL8723B.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RTL8723B.c new file mode 100755 index 000000000000..f2defeb3381e --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RTL8723B.c @@ -0,0 +1,71 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//============================================================ +// include files +//============================================================ + +#include "Mp_Precomp.h" +#include "../phydm_precomp.h" + +#if (RTL8723B_SUPPORT == 1) + + s1Byte +odm_CCKRSSI_8723B( + IN u1Byte LNA_idx, + IN u1Byte VGA_idx + ) +{ + s1Byte rx_pwr_all=0x00; + switch(LNA_idx) + { + //46 53 73 95 201301231630 + // 46 53 77 99 201301241630 + + case 6: + rx_pwr_all = -34 - (2 * VGA_idx); + break; + case 4: + rx_pwr_all = -14 - (2 * VGA_idx); + break; + case 1: + rx_pwr_all = 6 - (2 * VGA_idx); + break; + case 0: + rx_pwr_all = 16 - (2 * VGA_idx); + break; + default: + //rx_pwr_all = -53+(2*(31-VGA_idx)); + //DbgPrint("wrong LNA index\n"); + break; + + } + return rx_pwr_all; +} + +#endif // end if RTL8723B + + + + + + + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RTL8723B.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RTL8723B.h new file mode 100755 index 000000000000..c41a6965c23c --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RTL8723B.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __ODM_RTL8723B_H__ +#define __ODM_RTL8723B_H__ + +s1Byte +odm_CCKRSSI_8723B( + IN u1Byte LNA_idx, + IN u1Byte VGA_idx + ); + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RegConfig8723B.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RegConfig8723B.c new file mode 100755 index 000000000000..d30e60ed31d7 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RegConfig8723B.c @@ -0,0 +1,235 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#include "Mp_Precomp.h" +#include "../phydm_precomp.h" + +#if (RTL8723B_SUPPORT == 1) + +void +odm_ConfigRFReg_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data, + IN ODM_RF_RADIO_PATH_E RF_PATH, + IN u4Byte RegAddr + ) +{ + if(Addr == 0xfe || Addr == 0xffe) + { + #ifdef CONFIG_LONG_DELAY_ISSUE + ODM_sleep_ms(50); + #else + ODM_delay_ms(50); + #endif + } + else + { + ODM_SetRFReg(pDM_Odm, RF_PATH, RegAddr, bRFRegOffsetMask, Data); + // Add 1us delay between BB/RF register setting. + ODM_delay_us(1); + + //For disable/enable test in high temperature, the B6 value will fail to fill. Suggestion by BB Stanley, 2013.06.25. + if(Addr == 0xb6) + { + u4Byte getvalue=0; + u1Byte count =0; + getvalue = ODM_GetRFReg(pDM_Odm, RF_PATH, Addr, bMaskDWord); + + ODM_delay_us(1); + + while((getvalue>>8)!=(Data>>8)) + { + count++; + ODM_SetRFReg(pDM_Odm, RF_PATH, RegAddr, bRFRegOffsetMask, Data); + ODM_delay_us(1); + getvalue = ODM_GetRFReg(pDM_Odm, RF_PATH, Addr, bMaskDWord); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigRFWithHeaderFile: [B6] getvalue 0x%x, Data 0x%x, count %d\n", getvalue, Data,count)); + if(count>5) + break; + } + } + + if(Addr == 0xb2) + { + u4Byte getvalue=0; + u1Byte count =0; + getvalue = ODM_GetRFReg(pDM_Odm, RF_PATH, Addr, bMaskDWord); + + ODM_delay_us(1); + + while(getvalue!=Data) + { + count++; + ODM_SetRFReg(pDM_Odm, RF_PATH, RegAddr, bRFRegOffsetMask, Data); + ODM_delay_us(1); + //Do LCK againg + ODM_SetRFReg(pDM_Odm, RF_PATH, 0x18, bRFRegOffsetMask, 0x0fc07); + ODM_delay_us(1); + getvalue = ODM_GetRFReg(pDM_Odm, RF_PATH, Addr, bMaskDWord); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigRFWithHeaderFile: [B2] getvalue 0x%x, Data 0x%x, count %d\n", getvalue, Data,count)); + if(count>5) + break; + } + } + } +} + + +void +odm_ConfigRF_RadioA_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data + ) +{ + u4Byte content = 0x1000; // RF_Content: radioa_txt + u4Byte maskforPhySet= (u4Byte)(content&0xE000); + + odm_ConfigRFReg_8723B(pDM_Odm, Addr, Data, ODM_RF_PATH_A, Addr|maskforPhySet); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigRFWithHeaderFile: [RadioA] %08X %08X\n", Addr, Data)); +} + +void +odm_ConfigRF_RadioB_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data + ) +{ + u4Byte content = 0x1001; // RF_Content: radiob_txt + u4Byte maskforPhySet= (u4Byte)(content&0xE000); + + odm_ConfigRFReg_8723B(pDM_Odm, Addr, Data, ODM_RF_PATH_B, Addr|maskforPhySet); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigRFWithHeaderFile: [RadioB] %08X %08X\n", Addr, Data)); + +} + +void +odm_ConfigMAC_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u1Byte Data + ) +{ + ODM_Write1Byte(pDM_Odm, Addr, Data); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigMACWithHeaderFile: [MAC_REG] %08X %08X\n", Addr, Data)); +} + +void +odm_ConfigBB_AGC_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ) +{ + ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); + // Add 1us delay between BB/RF register setting. + ODM_delay_us(1); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigBBWithHeaderFile: [AGC_TAB] %08X %08X\n", Addr, Data)); +} + +void +odm_ConfigBB_PHY_REG_PG_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Band, + IN u4Byte RfPath, + IN u4Byte TxNum, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ) +{ + if (Addr == 0xfe || Addr == 0xffe) + #ifdef CONFIG_LONG_DELAY_ISSUE + ODM_sleep_ms(50); + #else + ODM_delay_ms(50); + #endif + else + { +#if !(DM_ODM_SUPPORT_TYPE&ODM_AP) + PHY_StoreTxPowerByRate(pDM_Odm->Adapter, Band, RfPath, TxNum, Addr, Bitmask, Data); +#endif + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ConfigBBWithHeaderFile: [PHY_REG] %08X %08X %08X\n", Addr, Bitmask, Data)); +} + +void +odm_ConfigBB_PHY_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ) +{ + if (Addr == 0xfe) + #ifdef CONFIG_LONG_DELAY_ISSUE + ODM_sleep_ms(50); + #else + ODM_delay_ms(50); + #endif + else if (Addr == 0xfd) + ODM_delay_ms(5); + else if (Addr == 0xfc) + ODM_delay_ms(1); + else if (Addr == 0xfb) + ODM_delay_us(50); + else if (Addr == 0xfa) + ODM_delay_us(5); + else if (Addr == 0xf9) + ODM_delay_us(1); + else + { + ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); + } + + // Add 1us delay between BB/RF register setting. + ODM_delay_us(1); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigBBWithHeaderFile: [PHY_REG] %08X %08X\n", Addr, Data)); +} + +void +odm_ConfigBB_TXPWR_LMT_8723B( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte Regulation, + IN pu1Byte Band, + IN pu1Byte Bandwidth, + IN pu1Byte RateSection, + IN pu1Byte RfPath, + IN pu1Byte Channel, + IN pu1Byte PowerLimit + ) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + PHY_SetTxPowerLimit(pDM_Odm, Regulation, Band, + Bandwidth, RateSection, RfPath, Channel, PowerLimit); +#elif (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + PHY_SetTxPowerLimit(pDM_Odm->Adapter, Regulation, Band, + Bandwidth, RateSection, RfPath, Channel, PowerLimit); +#endif +} + +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RegConfig8723B.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RegConfig8723B.h new file mode 100755 index 000000000000..4f2d3884e314 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/OUTSRC/rtl8723b/phydm_RegConfig8723B.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __INC_ODM_REGCONFIG_H_8723B +#define __INC_ODM_REGCONFIG_H_8723B + +#if (RTL8723B_SUPPORT == 1) + +void +odm_ConfigRFReg_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data, + IN ODM_RF_RADIO_PATH_E RF_PATH, + IN u4Byte RegAddr + ); + +void +odm_ConfigRF_RadioA_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data + ); + +void +odm_ConfigRF_RadioB_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data + ); + +void +odm_ConfigMAC_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u1Byte Data + ); + +void +odm_ConfigBB_AGC_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_PHY_REG_PG_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Band, + IN u4Byte RfPath, + IN u4Byte TxNum, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_PHY_8723B( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_TXPWR_LMT_8723B( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte Regulation, + IN pu1Byte Band, + IN pu1Byte Bandwidth, + IN pu1Byte RateSection, + IN pu1Byte RfPath, + IN pu1Byte Channel, + IN pu1Byte PowerLimit + ); + +#endif +#endif // end of SUPPORT + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_btcoex.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_btcoex.c index 221226abb177..119aaf78ef5e 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_btcoex.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_btcoex.c @@ -77,9 +77,27 @@ const char *const ioStaString[] = "h2c stopped", }; +const char *const GLBtcWifiBwString[]={ + "11bg", + "HT20", + "HT40", + "HT80", + "HT160" +}; + +const char *const GLBtcWifiFreqString[]={ + "2.4G", + "5G" +}; + +#define HALBTCOUTSRC_AGG_CHK_WINDOW_IN_MS 8000 + BTC_COEXIST GLBtCoexist; u8 GLBtcWiFiInScanState; u8 GLBtcWiFiInIQKState; +u8 GLBtcWiFiInIPS; +u8 GLBtcWiFiInLPS; +u8 GLBtcBtCoexAliveRegistered; u32 GLBtcDbgType[BTC_MSG_MAX]; u8 GLBtcDbgBuf[BT_TMP_BUF_SIZE]; @@ -269,6 +287,9 @@ void halbtcoutsrc_LeaveLowPower(PBTC_COEXIST pBtCoexist) timeout = 30; #endif // !LPS_RPWM_WAIT_MS + if (GLBtcBtCoexAliveRegistered == _TRUE) + return; + stime = rtw_get_current_time(); do { ready = rtw_register_task_alive(padapter, BTCOEX_ALIVE); @@ -281,6 +302,8 @@ void halbtcoutsrc_LeaveLowPower(PBTC_COEXIST pBtCoexist) rtw_msleep_os(1); } while (1); + + GLBtcBtCoexAliveRegistered = _TRUE; #endif // CONFIG_LPS_LCLK } @@ -293,9 +316,13 @@ void halbtcoutsrc_NormalLowPower(PBTC_COEXIST pBtCoexist) #ifdef CONFIG_LPS_LCLK PADAPTER padapter; + if (GLBtcBtCoexAliveRegistered == _FALSE) + return; padapter = pBtCoexist->Adapter; rtw_unregister_task_alive(padapter, BTCOEX_ALIVE); + + GLBtcBtCoexAliveRegistered = _FALSE; #endif // CONFIG_LPS_LCLK } @@ -311,16 +338,41 @@ void halbtcoutsrc_DisableLowPower(PBTC_COEXIST pBtCoexist, u8 bLowPwrDisable) void halbtcoutsrc_AggregationCheck(PBTC_COEXIST pBtCoexist) { PADAPTER padapter; - BOOLEAN bNeedToAct; - + BOOLEAN bNeedToAct = _FALSE; + static u32 preTime = 0; + u32 curTime = 0; padapter = pBtCoexist->Adapter; - bNeedToAct = _FALSE; + + //===================================== + // To void continuous deleteBA=>addBA=>deleteBA=>addBA + // This function is not allowed to continuous called. + // It can only be called after 8 seconds. + //===================================== + + curTime = rtw_systime_to_ms(rtw_get_current_time()); + if((curTime - preTime) < HALBTCOUTSRC_AGG_CHK_WINDOW_IN_MS) // over 8 seconds you can execute this function again. + { + return; + } + else + { + preTime = curTime; + } if (pBtCoexist->btInfo.bRejectAggPkt) + { rtw_btcoex_RejectApAggregatedPacket(padapter, _TRUE); + pBtCoexist->btInfo.bPreRejectAggPkt = pBtCoexist->btInfo.bRejectAggPkt; + } else { + if(pBtCoexist->btInfo.bPreRejectAggPkt) + { + bNeedToAct = _TRUE; + pBtCoexist->btInfo.bPreRejectAggPkt = pBtCoexist->btInfo.bRejectAggPkt; + } + if (pBtCoexist->btInfo.bPreBtCtrlAggBufSize != pBtCoexist->btInfo.bBtCtrlAggBufSize) { @@ -515,10 +567,10 @@ static u8 halbtcoutsrc_GetWifiScanAPNum(PADAPTER padapter) pmlmeext = &padapter->mlmeextpriv; if (GLBtcWiFiInScanState == _FALSE) { - if (pmlmeext->sitesurvey_res.bss_cnt > 0xFF) + if (pmlmepriv->num_of_scanned > 0xFF) scan_AP_num = 0xFF; else - scan_AP_num = (u8)pmlmeext->sitesurvey_res.bss_cnt; + scan_AP_num = (u8)pmlmepriv->num_of_scanned; } return scan_AP_num; @@ -658,6 +710,10 @@ u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) case BTC_GET_BL_EXT_SWITCH: *pu8 = _FALSE; break; + case BTC_GET_BL_IS_ASUS_8723B: + /* Always return FALSE in linux driver since this case is added only for windows driver */ + *pu8 = _FALSE; + break; case BTC_GET_S4_WIFI_RSSI: *pS4Tmp = halbtcoutsrc_GetWifiRssi(padapter); @@ -727,6 +783,9 @@ u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) case BTC_GET_U1_AP_NUM: *pU1Tmp = halbtcoutsrc_GetWifiScanAPNum(padapter); break; + case BTC_GET_U1_ANT_TYPE: + *pU1Tmp = (u1Byte)BTC_ANT_TYPE_0; + break; //=======1Ant=========== case BTC_GET_U1_LPS_MODE: @@ -870,15 +929,24 @@ u8 halbtcoutsrc_Set(void *pBtcContext, u8 setType, void *pInBuf) break; case BTC_SET_ACT_SEND_MIMO_PS: -#if 0 // not implement yet { - u8 newMimoPsMode = *pU1Tmp; + u8 newMimoPsMode = 3; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + // *pU1Tmp = 0 use SM_PS static type + // *pU1Tmp = 1 disable SM_PS + if(*pU1Tmp==0) + newMimoPsMode = WLAN_HT_CAP_SM_PS_STATIC; + else if(*pU1Tmp==1) + newMimoPsMode = WLAN_HT_CAP_SM_PS_DISABLED; + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) - SendMimoPsFrame(padapter, padapter->MgntInfo.Bssid, newMimoPsMode); + { + //issue_action_SM_PS(padapter, get_my_bssid(&(pmlmeinfo->network)), newMimoPsMode); + issue_action_SM_PS_wait_ack(padapter, get_my_bssid(&(pmlmeinfo->network)), newMimoPsMode, 3, 1); + } } -#else - ret = _FALSE; -#endif break; case BTC_SET_ACT_CTRL_BT_INFO: @@ -936,6 +1004,48 @@ u8 halbtcoutsrc_Set(void *pBtcContext, u8 setType, void *pInBuf) return ret; } +u8 halbtcoutsrc_UnderIps(PBTC_COEXIST pBtCoexist) +{ + PADAPTER padapter; + struct pwrctrl_priv *pwrpriv; + u8 bMacPwrCtrlOn; + + padapter = pBtCoexist->Adapter; + pwrpriv = &padapter->dvobj->pwrctl_priv; + bMacPwrCtrlOn = _FALSE; + + if ((_TRUE == pwrpriv->bips_processing) + && (IPS_NONE != pwrpriv->ips_mode_req) + ) + { + return _TRUE; + } + + if (rf_off == pwrpriv->rf_pwrstate) + { + return _TRUE; + } + + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if (_FALSE == bMacPwrCtrlOn) + { + return _TRUE; + } + + return _FALSE; +} + +u8 halbtcoutsrc_UnderLps(PBTC_COEXIST pBtCoexist) +{ + return GLBtcWiFiInLPS; +} + +u8 halbtcoutsrc_Under32K(PBTC_COEXIST pBtCoexist) +{ + /* todo: the method to check whether wifi is under 32K or not */ + return _FALSE; +} + void halbtcoutsrc_DisplayCoexStatistics(PBTC_COEXIST pBtCoexist) { #if 0 @@ -1036,17 +1146,95 @@ void halbtcoutsrc_DisplayBtLinkInfo(PBTC_COEXIST pBtCoexist) #endif } -void halbtcoutsrc_DisplayFwPwrModeCmd(PBTC_COEXIST pBtCoexist) +void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist) { - u8 *cliBuf = pBtCoexist->cliBuf; + PADAPTER padapter = pBtCoexist->Adapter; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8* cliBuf=pBtCoexist->cliBuf; + s32 wifiRssi=0, btHsRssi=0; + BOOLEAN bScan=_FALSE, bLink=_FALSE, bRoam=_FALSE, bWifiBusy=_FALSE, bWifiUnderBMode=_FALSE; + u32 wifiBw=BTC_WIFI_BW_HT20, wifiTrafficDir=BTC_WIFI_TRAFFIC_TX, wifiFreq=BTC_FREQ_2_4G; + u32 wifiLinkStatus=0x0; + BOOLEAN bBtHsOn=_FALSE, bLowPower=_FALSE; + u8 wifiChnl=0, wifiHsChnl=0, nScanAPNum = 0, FwPSState; - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x ", "Power mode cmd ", \ + wifiLinkStatus = halbtcoutsrc_GetWifiLinkStatus(pBtCoexist); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "STA/vWifi/HS/p2pGo/p2pGc", \ + ((wifiLinkStatus&WIFI_STA_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_AP_CONNECTED)? 1:0), + ((wifiLinkStatus&WIFI_HS_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_P2P_GO_CONNECTED)? 1:0), + ((wifiLinkStatus&WIFI_P2P_GC_CONNECTED)? 1:0) ); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiChnl); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(High Speed)", \ + wifiChnl, wifiHsChnl, bBtHsOn); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \ + wifiRssi-100, btHsRssi-100); + CL_PRINTF(cliBuf); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \ + bLink, bRoam, bScan); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifiFreq); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &nScanAPNum); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s/ AP=%d ", "Wifi freq/ bw/ traffic", \ + GLBtcWifiFreqString[wifiFreq], ((bWifiUnderBMode)? "11b": GLBtcWifiBwString[wifiBw]), + ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink")), + nScanAPNum); + CL_PRINTF(cliBuf); + + // power status + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s%s%s", "Power Status", \ + ((halbtcoutsrc_UnderIps(pBtCoexist) == _TRUE)? "IPS ON":"IPS OFF"), + ((halbtcoutsrc_UnderLps(pBtCoexist) == _TRUE)? ", LPS ON":", LPS OFF"), + ((halbtcoutsrc_Under32K(pBtCoexist) == _TRUE)? ", 32k":"")); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x (0x%x/0x%x)", "Power mode cmd(lps/rpwm)", \ pBtCoexist->pwrModeVal[0], pBtCoexist->pwrModeVal[1], pBtCoexist->pwrModeVal[2], pBtCoexist->pwrModeVal[3], - pBtCoexist->pwrModeVal[4], pBtCoexist->pwrModeVal[5]); + pBtCoexist->pwrModeVal[4], pBtCoexist->pwrModeVal[5], + pBtCoexist->btInfo.lpsVal, + pBtCoexist->btInfo.rpwmVal); CL_PRINTF(cliBuf); } +void halbtcoutsrc_DisplayDbgMsg(void *pBtcContext, u8 dispType) +{ + PBTC_COEXIST pBtCoexist; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + switch(dispType) + { + case BTC_DBG_DISP_COEX_STATISTICS: + halbtcoutsrc_DisplayCoexStatistics(pBtCoexist); + break; + case BTC_DBG_DISP_BT_LINK_INFO: + halbtcoutsrc_DisplayBtLinkInfo(pBtCoexist); + break; + case BTC_DBG_DISP_WIFI_STATUS: + halbtcoutsrc_DisplayWifiStatus(pBtCoexist); + break; + default: + break; + } +} + //==================================== // IO related function //==================================== @@ -1111,7 +1299,7 @@ void halbtcoutsrc_BitMaskWrite1Byte(void *pBtcContext, u32 regAddr, u8 bitMask, originalValue = 0; bitShift = 0; - if (bitMask != 0xFF) + if(bitMask != 0xff) { originalValue = rtw_read8(padapter, regAddr); @@ -1267,59 +1455,6 @@ void halbtcoutsrc_FillH2cCmd(void *pBtcContext, u8 elementId, u32 cmdLen, u8 *pC rtw_hal_fill_h2c_cmd(padapter, elementId, cmdLen, pCmdBuffer); } -void halbtcoutsrc_DisplayDbgMsg(void *pBtcContext, u8 dispType) -{ - PBTC_COEXIST pBtCoexist; - - - pBtCoexist = (PBTC_COEXIST)pBtcContext; - switch(dispType) - { - case BTC_DBG_DISP_COEX_STATISTICS: - halbtcoutsrc_DisplayCoexStatistics(pBtCoexist); - break; - case BTC_DBG_DISP_BT_LINK_INFO: - halbtcoutsrc_DisplayBtLinkInfo(pBtCoexist); - break; - case BTC_DBG_DISP_FW_PWR_MODE_CMD: - halbtcoutsrc_DisplayFwPwrModeCmd(pBtCoexist); - break; - default: - break; - } -} - -u8 halbtcoutsrc_UnderIps(PBTC_COEXIST pBtCoexist) -{ - PADAPTER padapter; - struct pwrctrl_priv *pwrpriv; - u8 bMacPwrCtrlOn; - - padapter = pBtCoexist->Adapter; - pwrpriv = &padapter->dvobj->pwrctl_priv; - bMacPwrCtrlOn = _FALSE; - - if ((_TRUE == pwrpriv->bips_processing) - && (IPS_NONE != pwrpriv->ips_mode_req) - ) - { - return _TRUE; - } - - if (rf_off == pwrpriv->rf_pwrstate) - { - return _TRUE; - } - - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); - if (_FALSE == bMacPwrCtrlOn) - { - return _TRUE; - } - - return _FALSE; -} - //==================================== // Extern functions called by other module //==================================== @@ -1408,6 +1543,12 @@ u8 EXhalbtcoutsrc_InitlizeVariables(void *padapter) GLBtcWiFiInIQKState = _FALSE; + GLBtcWiFiInIPS = _FALSE; + + GLBtcWiFiInLPS = _FALSE; + + GLBtcBtCoexAliveRegistered = _FALSE; + return _TRUE; } @@ -1426,6 +1567,22 @@ void EXhalbtcoutsrc_PowerOnSetting(PBTC_COEXIST pBtCoexist) } } +void EXhalbtcoutsrc_PreLoadFirmware(PBTC_COEXIST pBtCoexist) +{ + if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->statistics.cntPreLoadFirmware++; + + if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if(pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_PreLoadFirmware(pBtCoexist); + else if(pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_PreLoadFirmware(pBtCoexist); + } +} + void EXhalbtcoutsrc_InitHwConfig(PBTC_COEXIST pBtCoexist, u8 bWifiOnly) { if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) @@ -1548,10 +1705,16 @@ void EXhalbtcoutsrc_IpsNotify(PBTC_COEXIST pBtCoexist, u8 type) return; if (IPS_NONE == type) + { ipsType = BTC_IPS_LEAVE; + GLBtcWiFiInIPS = _FALSE; + } else + { ipsType = BTC_IPS_ENTER; - + GLBtcWiFiInIPS = _TRUE; + } + // All notify is called in cmd thread, don't need to leave low power again // halbtcoutsrc_LeaveLowPower(pBtCoexist); @@ -1617,10 +1780,16 @@ void EXhalbtcoutsrc_LpsNotify(PBTC_COEXIST pBtCoexist, u8 type) return; if (PS_MODE_ACTIVE == type) + { lpsType = BTC_LPS_DISABLE; + GLBtcWiFiInLPS = _FALSE; + } else + { lpsType = BTC_LPS_ENABLE; - + GLBtcWiFiInLPS = _TRUE; + } + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) { if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) @@ -2301,6 +2470,35 @@ void EXhalbtcoutsrc_DbgControl(PBTC_COEXIST pBtCoexist, u8 opCode, u8 opLen, u8 // halbtcoutsrc_NormalLowPower(pBtCoexist); } +#if 0 +VOID +EXhalbtcoutsrc_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + /* Need to refine the following power save operations to enable this function in the future */ +#if 0 + IPSDisable(pBtCoexist->Adapter, FALSE, 0); + LeisurePSLeave(pBtCoexist->Adapter, LPS_DISABLE_BT_COEX); +#endif + + if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if(pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_AntennaDetection(pBtCoexist, centFreq, offset, span, seconds); + } + + //IPSReturn(pBtCoexist->Adapter, 0xff); +} +#endif + void EXhalbtcoutsrc_StackUpdateProfileInfo(void) { #if 0 @@ -2521,6 +2719,25 @@ void EXhalbtcoutsrc_DisplayBtCoexInfo(PBTC_COEXIST pBtCoexist) halbtcoutsrc_NormalLowPower(pBtCoexist); } +VOID +EXhalbtcoutsrc_DisplayAntIsolation( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if(pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_DisplayAntIsolation(pBtCoexist); + } + + halbtcoutsrc_NormalLowPower(pBtCoexist); +} + static void halbt_InitHwConfig92C(PADAPTER padapter) { PHAL_DATA_TYPE pHalData; @@ -2680,6 +2897,11 @@ void hal_btcoex_PowerOnSetting(PADAPTER padapter) EXhalbtcoutsrc_PowerOnSetting(&GLBtCoexist); } +void hal_btcoex_PreLoadFirmware(PADAPTER padapter) +{ + EXhalbtcoutsrc_PreLoadFirmware(&GLBtCoexist); +} + void hal_btcoex_InitHwConfig(PADAPTER padapter, u8 bWifiOnly) { if (!hal_btcoex_IsBtExist(padapter)) @@ -2833,13 +3055,15 @@ u8 hal_btcoex_LpsVal(PADAPTER padapter) u32 hal_btcoex_GetRaMask(PADAPTER padapter) { if (!hal_btcoex_IsBtExist(padapter)) - return 0; + return 0; if (GLBtCoexist.btInfo.bBtDisabled) - return 0; + return 0; - if (GLBtCoexist.boardInfo.btdmAntNum != 1) - return 0; + // Modify by YiWei , suggest by Cosa and Jenyu + // Remove the limit antenna number , because 2 antenna case (ex: 8192eu)also want to get BT coex report rate mask. + //if (GLBtCoexist.boardInfo.btdmAntNum != 1) + // return 0; return GLBtCoexist.btInfo.raMask; } @@ -3021,5 +3245,183 @@ u8 hal_btcoex_IsBtLinkExist(PADAPTER padapter) return _FALSE; } + +/* + * Description: + * Setting BT coex antenna isolation type . + * coex mechanisn/ spital stream/ best throughput + * anttype = 0 , PSTDMA / 2SS / 0.5T , bad isolation (<20dB) for 2,3 antenna + * anttype = 1 , PSTDMA / 1SS / 0.5T , normal isolaiton (>20dB) for 2 antenna + * anttype = 2 , TDMA / 2SS / T , normal isolaiton (>20dB) for 3 antenna + * anttype = 3 , no TDMA / 1SS / 0.5T , good isolation (>40dB) for 2 antenna + * anttype = 4 , no TDMA / 2SS / T , good isolation (>40dB) for 3 antenna + * wifi only throughput ~ T + * wifi/BT share one antenna with SPDT + */ +void hal_btcoex_SetAntIsolationType(PADAPTER padapter, u8 anttype) +{ + PHAL_DATA_TYPE pHalData; + + //DBG_871X("####%s , anttype = %d , %d \n", __FUNCTION__,anttype,__LINE__); + pHalData = GET_HAL_DATA(padapter); + + + pHalData->bt_coexist.btAntisolation= anttype; + +} + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +int +hal_btcoex_ParseAntIsolationConfigFile( + PADAPTER Adapter, + char* buffer +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 i = 0 , j=0; + char *szLine, *ptmp; + int rtStatus = _SUCCESS; + char param_value_string[10]; + u8 param_value; + u8 anttype = 4; + + u8 ant_num=3, ant_distance=50; + + typedef struct ant_isolation + { + char *param_name; // antenna isolation config parameter name + u8 *value; // antenna isolation config parameter value + }ANT_ISOLATION; + + ANT_ISOLATION ant_isolation_param[]= { + {"ANT_NUMBER",&ant_num}, + {"ANT_DISTANCE",&ant_distance}, + {NULL,0} + }; + + + + //DBG_871X("===>Hal_ParseAntIsolationConfigFile()\n" ); + + ptmp = buffer; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + // skip comment + if ( IsCommentString( szLine ) ) { + continue; + } + + //DBG_871X("%s : szLine = %s , strlen(szLine) = %d \n", __FUNCTION__,szLine,strlen(szLine)); + for ( j=0 ;ant_isolation_param[j].param_name != NULL ; j++ ) + { + if ( strstr(szLine,ant_isolation_param[j].param_name)!= NULL ) + { + i=0; + while ( i < strlen(szLine) ) + { + if (szLine[i] != '"') + ++i; + else + { + // skip only has one " + if( strpbrk(szLine, "\"") == strrchr(szLine, '"')) + { + DBG_871X("Fail to parse parameters , format error!\n"); + break; + } + _rtw_memset( ( PVOID ) param_value_string, 0, 10 ); + if ( ! ParseQualifiedString( szLine, &i, param_value_string, '"' , '"' ) ) { + DBG_871X("Fail to parse parameters \n"); + return _FAIL; + } + else + { + GetU1ByteIntegerFromStringInDecimal( param_value_string, ant_isolation_param[j].value ); + } + break; + } + } + } + } + } + + // YiWei 20140716 , for BT coex antenna isolation control + if ( ant_num==3 && ant_distance>=50) + { + pHalData->EEPROMBluetoothCoexist = 0; + anttype = 4; + } + else if ( ant_num==2 && ant_distance>=50 ) + { + anttype = 3; + } + else if ( ant_num==3 && ant_distance>=15 && ant_distance<50 ) + { + anttype = 2; + } + else if ( ant_num==2 && ant_distance>=15 && ant_distance<50 ) + { + anttype = 1; + } + else if ( (ant_num==2 && ant_distance<15) || (ant_num==3 && ant_distance<15)) + { + anttype = 0; + } + else + { + pHalData->EEPROMBluetoothCoexist = 1; + anttype = 1; + } + + hal_btcoex_SetAntIsolationType(Adapter, anttype); + + DBG_871X("%s : ant_num = %d \n", __FUNCTION__,ant_num); + DBG_871X("%s : ant_distance = %d \n", __FUNCTION__,ant_distance); + //DBG_871X("<===Hal_ParseAntIsolationConfigFile()\n"); + return rtStatus; +} + + +int +hal_btcoex_AntIsolationConfig_ParaFile( + IN PADAPTER Adapter, + IN char* pFileName +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rlen = 0, rtStatus = _FAIL; + //char file_path[1024]; + + //if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE)) + // return rtStatus; + + _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN); + + + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrive_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + } + } + + + if(rtStatus == _SUCCESS) + { + //DBG_871X("%s(): read %s ok\n", __FUNCTION__, pFileName); + rtStatus = hal_btcoex_ParseAntIsolationConfigFile( Adapter, pHalData->para_file_buf ); + } + else + { + DBG_871X("%s(): No File %s, Load from *** Array!\n", __FUNCTION__, pFileName); + } + + return rtStatus; +} +#endif // CONFIG_LOAD_PHY_PARA_FROM_FILE #endif // CONFIG_BT_COEXIST diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com.c index 9e1dfe53ada5..bf5256f0b80c 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com.c @@ -22,11 +22,17 @@ #include #include "hal_com_h2c.h" -#include "../hal/OUTSRC/odm_precomp.h" +#include "hal_data.h" + +//#define CONFIG_GTK_OL_DBG + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +char file_path[PATH_LENGTH_MAX]; +#endif u8 rtw_hal_data_init(_adapter *padapter) { - if(is_primary_adapter(padapter)) //if(padapter->isprimary) + if(is_primary_adapter(padapter)) { padapter->hal_data_sz = sizeof(HAL_DATA_TYPE); padapter->HalData = rtw_zvmalloc(padapter->hal_data_sz); @@ -34,19 +40,19 @@ u8 rtw_hal_data_init(_adapter *padapter) DBG_8192C("cant not alloc memory for HAL DATA \n"); return _FAIL; } - } + } return _SUCCESS; } void rtw_hal_data_deinit(_adapter *padapter) { - if(is_primary_adapter(padapter)) //if(padapter->isprimary) + if(is_primary_adapter(padapter)) { if (padapter->HalData) { #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE phy_free_filebuf(padapter); - #endif + #endif rtw_vmfree(padapter->HalData, padapter->hal_data_sz); padapter->HalData = NULL; padapter->hal_data_sz = 0; @@ -54,7 +60,6 @@ void rtw_hal_data_deinit(_adapter *padapter) } } - void dump_chip_info(HAL_VERSION ChipVersion) { int cnt = 0; @@ -957,87 +962,4066 @@ void hw_var_port_switch(_adapter *adapter) for (i=0; i<6; i++) rtw_write8(adapter, REG_BSSID1+i, bssid[i]); - /* write bcn ctl */ -#ifdef CONFIG_BT_COEXIST -#if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B) - // always enable port0 beacon function for PSTDMA - bcn_ctrl_1 |= EN_BCN_FUNCTION; - // always disable port1 beacon function for PSTDMA - bcn_ctrl &= ~EN_BCN_FUNCTION; -#endif -#endif - rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1); - rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl); + /* write bcn ctl */ +#ifdef CONFIG_BT_COEXIST +#if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B) + // always enable port0 beacon function for PSTDMA + bcn_ctrl_1 |= EN_BCN_FUNCTION; + // always disable port1 beacon function for PSTDMA + bcn_ctrl &= ~EN_BCN_FUNCTION; +#endif +#endif + rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1); + rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl); + + if (adapter->iface_type == IFACE_PORT0) { + adapter->iface_type = IFACE_PORT1; + adapter->pbuddy_adapter->iface_type = IFACE_PORT0; + DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n", + ADPT_ARG(adapter->pbuddy_adapter), ADPT_ARG(adapter)); + } else { + adapter->iface_type = IFACE_PORT0; + adapter->pbuddy_adapter->iface_type = IFACE_PORT1; + DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n", + ADPT_ARG(adapter), ADPT_ARG(adapter->pbuddy_adapter)); + } + +#ifdef DBG_RUNTIME_PORT_SWITCH + msr = rtw_read8(adapter, MSR); + bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL); + bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1); + + for (i=0; i<2; i++) + atimwnd[i] = rtw_read8(adapter, REG_ATIMWND+i); + for (i=0; i<2; i++) + atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1+i); + + for (i=0; i<8; i++) + tsftr[i] = rtw_read8(adapter, REG_TSFTR+i); + for (i=0; i<8; i++) + tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1+i); + + for (i=0; i<6; i++) + macid[i] = rtw_read8(adapter, REG_MACID+i); + + for (i=0; i<6; i++) + bssid[i] = rtw_read8(adapter, REG_BSSID+i); + + for (i=0; i<6; i++) + macid_1[i] = rtw_read8(adapter, REG_MACID1+i); + + for (i=0; i<6; i++) + bssid_1[i] = rtw_read8(adapter, REG_BSSID1+i); + + DBG_871X(FUNC_ADPT_FMT" after switch\n" + "msr:0x%02x\n" + "bcn_ctrl:0x%02x\n" + "bcn_ctrl_1:0x%02x\n" + "atimwnd:%u\n" + "atimwnd_1:%u\n" + "tsftr:%llu\n" + "tsftr1:%llu\n" + "macid:"MAC_FMT"\n" + "bssid:"MAC_FMT"\n" + "macid_1:"MAC_FMT"\n" + "bssid_1:"MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter) + , msr + , bcn_ctrl + , bcn_ctrl_1 + , *((u16*)atimwnd) + , *((u16*)atimwnd_1) + , *((u64*)tsftr) + , *((u64*)tsftr_1) + , MAC_ARG(macid) + , MAC_ARG(bssid) + , MAC_ARG(macid_1) + , MAC_ARG(bssid_1) + ); +#endif /* DBG_RUNTIME_PORT_SWITCH */ + +#endif /* CONFIG_RUNTIME_PORT_SWITCH */ +#endif /* CONFIG_CONCURRENT_MODE */ +} + +void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc) +{ + struct hal_ops *pHalFunc = &padapter->HalFunc; + u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0}; + u8 ret = 0; + + DBG_871X("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n", + rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll, + rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull, + rsvdpageloc->LocBTQosNull); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp); + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll); + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData); + SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull); + SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull); + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(padapter, + H2C_RSVD_PAGE, + H2C_RSVDPAGE_LOC_LEN, + u1H2CRsvdPageParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } +} + +#ifdef CONFIG_GPIO_WAKEUP +static void rtw_hal_set_output_gpio(_adapter* padapter, u8 index, u8 outputval) +{ + u8 val8; + + + if ( index <= 7 ) { + /* config GPIO mode */ + rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3, + rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index) ); + + /* config GPIO Sel */ + /* 0: input */ + /* 1: output */ + rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2, + rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index)); + + /* set output value */ + if ( outputval ) { + rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1, + rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index)); + } else { + rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1, + rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index)); + } + } else if (index <= 15) { + /* 88C Series: */ + /* index: 11~8 transform to 3~0 */ + /* 8723 Series: */ + /* index: 12~8 transform to 4~0 */ +#ifdef CONFIG_RTL8723B + if ((index == 13) || (index == 14)) { + // Set BIT_GPIO13_14_WL_CTRL_EN to 0 + val8 = rtw_read8(padapter, 0x4e); + if (val8 & BIT(6)) { + val8 &= ~BIT(6); + rtw_write8(padapter, 0x4e, val8); + DBG_871X("%s: set GPIO%d to WL control, 0x4E=0x%02X\n", + __FUNCTION__, index, rtw_read8(padapter, 0x4e)); + } + } +#endif // CONFIG_RTL8723B + + index -= 8; + + /* config GPIO mode */ + rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3, + rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index) ); + + /* config GPIO Sel */ + /* 0: input */ + /* 1: output */ + rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2, + rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index)); + + /* set output value */ + if ( outputval ) { + rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1, + rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index)); + } else { + rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1, + rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index)); + } + } else { + DBG_871X("%s: invalid GPIO%d=%d\n", __FUNCTION__, index, outputval); + } +} + +/* + * Set GPIO high/low under init and + * fw will trigger Low/High Pulse when need to wake up host + */ +void rtw_clear_hostwakeupgpio(PADAPTER padapter) +{ + u8 high = 0; + + +#ifdef CONFIG_GPIO_WAKEUP_LOW_ACTIVE + high = 1; +#endif // CONFIG_GPIO_WAKEUP_LOW_ACTIVE + DBG_871X("%s: Set GPIO%d to %s for wake\n", + __FUNCTION__, WAKEUP_GPIO_IDX, high?"high":"low"); + rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, high); +} +#endif + +void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc) +{ + struct hal_ops *pHalFunc = &padapter->HalFunc; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 res = 0, count = 0, ret = 0; +#ifdef CONFIG_WOWLAN + u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0}; + + DBG_871X("AOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n", + rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp, + rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp, + rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq, + rsvdpageloc->LocNetList); + + if (check_fwstate(pmlmepriv, _FW_LINKED)) { + SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo); + SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp); + //SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv); + SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp); + SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo); +#ifdef CONFIG_GTK_OL + SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM); +#endif // CONFIG_GTK_OL + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(padapter, + H2C_AOAC_RSVD_PAGE, + H2C_AOAC_RSVDPAGE_LOC_LEN, + u1H2CAoacRsvdPageParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + } +#ifdef CONFIG_PNO_SUPPORT + else + { + + if(!pwrpriv->pno_in_resume) { + DBG_871X("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo); + _rtw_memset(&u1H2CAoacRsvdPageParm, 0, + sizeof(u1H2CAoacRsvdPageParm)); + SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm, + rsvdpageloc->LocPNOInfo); + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(padapter, + H2C_AOAC_RSVDPAGE3, + H2C_AOAC_RSVDPAGE_LOC_LEN, + u1H2CAoacRsvdPageParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + } + } +#endif //CONFIG_PNO_SUPPORT +#endif // CONFIG_WOWLAN +} + +#ifdef CONFIG_WOWLAN +// rtw_hal_check_wow_ctrl +// chk_type: _TRUE means to check enable, if 0x690 & bit1, WOW enable successful +// _FALSE means to check disable, if 0x690 & bit1, WOW disable fail +static u8 rtw_hal_check_wow_ctrl(_adapter* adapter, u8 chk_type) +{ + u8 mstatus = 0; + u8 trycnt = 25; + u8 res = _FALSE; + + mstatus = rtw_read8(adapter, REG_WOW_CTRL); + DBG_871X_LEVEL(_drv_info_, "%s mstatus:0x%02x\n", __func__, mstatus); + + if (chk_type) { + while(!(mstatus&BIT1) && trycnt>1) { + mstatus = rtw_read8(adapter, REG_WOW_CTRL); + DBG_871X_LEVEL(_drv_always_, + "Loop index: %d :0x%02x\n", + trycnt, mstatus); + trycnt --; + rtw_msleep_os(2); + } + if (mstatus & BIT1) + res = _TRUE; + else + res = _FALSE; + } else { + while (mstatus&BIT1 && trycnt>1) { + mstatus = rtw_read8(adapter, REG_WOW_CTRL); + DBG_871X_LEVEL(_drv_always_, + "Loop index: %d :0x%02x\n", + trycnt, mstatus); + trycnt --; + rtw_msleep_os(2); + } + + if (mstatus & BIT1) + res = _FALSE; + else + res = _TRUE; + } + DBG_871X_LEVEL(_drv_always_, "%s check_type: %d res: %d trycnt: %d\n", + __func__, chk_type, res, (25 - trycnt)); + return res; +} + +#ifdef CONFIG_PNO_SUPPORT +static u8 rtw_hal_check_pno_enabled(_adapter* adapter) +{ + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); + u8 res = 0, count = 0; + u8 ret = _FALSE; + if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) { + res = rtw_read8(adapter, REG_PNO_STATUS); + while(!(res&BIT(7)) && count < 25) { + DBG_871X("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", + count, res); + res = rtw_read8(adapter, REG_PNO_STATUS); + count++; + rtw_msleep_os(2); + } + if (res & BIT(7)) + ret = _TRUE; + else + ret = _FALSE; + DBG_871X("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret); + } + return ret; +} +#endif + +static void rtw_hal_force_enable_rxdma(_adapter* adapter) +{ + DBG_871X("%s: Set 0x690=0x00\n", __func__); + rtw_write8(adapter, REG_WOW_CTRL, + (rtw_read8(adapter, REG_WOW_CTRL)&0xf0)); + DBG_871X_LEVEL(_drv_always_, "%s: Release RXDMA\n", __func__); + rtw_write32(adapter, REG_RXPKT_NUM, + (rtw_read32(adapter,REG_RXPKT_NUM)&(~RW_RELEASE_EN))); +} + +static void rtw_hal_disable_tx_report(_adapter* adapter) +{ + rtw_write8(adapter, REG_TX_RPT_CTRL, + ((rtw_read8(adapter, REG_TX_RPT_CTRL)&~BIT(1)))&~BIT(5)); + DBG_871X("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL)); +} + +static void rtw_hal_enable_tx_report(_adapter* adapter) +{ + rtw_write8(adapter, REG_TX_RPT_CTRL, + ((rtw_read8(adapter, REG_TX_RPT_CTRL)|BIT(1)))|BIT(5)); + DBG_871X("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL)); +} + +void rtw_hal_fill_fake_txdesc(_adapter* padapter, u8* pDesc, u32 BufferLen, + u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame) +{ + + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct hal_ops *pHalFunc = &padapter->HalFunc; + struct tx_desc *ptxdesc; + + // Clear all status + _rtw_memset(pDesc, 0, TXDESC_SIZE); + + if (TXDESC_SIZE == 32) { + ptxdesc = (struct tx_desc*)pDesc; + //offset 0 + //own, bFirstSeg, bLastSeg; + ptxdesc->txdw0 |= + cpu_to_le32( BIT(31) | BIT(27)| BIT(26)); + + //32 bytes for TX Desc + ptxdesc->txdw0 |= + cpu_to_le32(((TXDESC_SIZE + 0) << 16)&0x00ff0000); + + // Buffer size + command header + ptxdesc->txdw0 |= + cpu_to_le32(BufferLen&0x0000ffff); + + //offset 4 + // Fixed queue of Mgnt queue + ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<< 8)&0x00001f00); + + //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. + if (IsPsPoll) { + ptxdesc->txdw1 |= cpu_to_le32(BIT(20)); + } else { + // Hw set sequence number + ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); + //set bit3 to 1. Suugested by TimChen. 2009.12.29. + ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); + } + + if (_TRUE == IsBTQosNull) { + ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); // BT NULL + } + + //offset 16 + //driver uses rate + ptxdesc->txdw4 |= cpu_to_le32(BIT(8)); + + } else if (TXDESC_SIZE == 40) { + SET_TX_DESC_FIRST_SEG(pDesc, 1); //bFirstSeg; + SET_TX_DESC_LAST_SEG(pDesc, 1); //bLastSeg; + + SET_TX_DESC_OFFSET(pDesc, TXDESC_SIZE); + + SET_TX_DESC_PKT_SIZE(pDesc, BufferLen); // Buffer size + command header + + if (pmlmeext->cur_wireless_mode & WIRELESS_11B) { + SET_TX_DESC_RATE_ID(pDesc, RATR_INX_WIRELESS_B); + } else { + SET_TX_DESC_RATE_ID(pDesc, RATR_INX_WIRELESS_G); + } + + SET_TX_DESC_QUEUE_SEL(pDesc, QSLT_MGNT); // Fixed queue of Mgnt queue + + // Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. + if (_TRUE == IsPsPoll) { + SET_TX_DESC_NAV_USE_HDR(pDesc, 1); + } else { + SET_TX_DESC_HWSEQ_EN(pDesc, 1); // Hw set sequence number + SET_TX_DESC_HWSEQ_SEL(pDesc, 0); + } + + if (_TRUE ==IsBTQosNull) { + SET_TX_DESC_BT_INT(pDesc, 1); + } + + SET_TX_DESC_USE_RATE(pDesc, 1); // use data rate which is set by Sw + SET_TX_DESC_OWN((pu1Byte)pDesc, 1); + + SET_TX_DESC_TX_RATE(pDesc, MRateToHwRate(pmlmeext->tx_rate)); + + } + + // + // Encrypt the data frame if under security mode excepct null data. + // Suggested by CCW. + // + if (_TRUE ==bDataFrame) + { + u32 EncAlg; + + EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm; + switch (EncAlg) + { + case _NO_PRIVACY_: + SET_TX_DESC_SEC_TYPE(pDesc, 0x0); + break; + case _WEP40_: + case _WEP104_: + case _TKIP_: + SET_TX_DESC_SEC_TYPE(pDesc, 0x1); + break; + case _SMS4_: + SET_TX_DESC_SEC_TYPE(pDesc, 0x2); + break; + case _AES_: + SET_TX_DESC_SEC_TYPE(pDesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE(pDesc, 0x0); + break; + } + } + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + // USB interface drop packet if the checksum of descriptor isn't correct. + // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). + if(pHalFunc->hal_cal_txdesc_chksum != NULL) +#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8723A) ||defined(CONFIG_RTL8723B) + pHalFunc->hal_cal_txdesc_chksum((struct tx_desc*)pDesc); +#else + pHalFunc->hal_cal_txdesc_chksum(pDesc); +#endif //CONFIG_RTL8188E || CONFIG_RTL8723B +#endif +} + +static void rtw_hal_backup_rate(_adapter* adapter) +{ + DBG_871X("%s\n", __func__); + //backup data rate to register 0x8b for wowlan FW + rtw_write8(adapter, 0x8d, 1); + rtw_write8(adapter, 0x8c, 0); + rtw_write8(adapter, 0x8f, 0x40); + rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0)); +} + +static u8 rtw_hal_pause_rx_dma(_adapter* adapter) +{ + u8 ret = 0; + u8 trycnt = 100; + u16 len = 0; + u32 tmp = 0; + int res = 0; + //RX DMA stop + DBG_871X_LEVEL(_drv_always_, "Pause DMA\n"); + rtw_write32(adapter, REG_RXPKT_NUM, + (rtw_read32(adapter,REG_RXPKT_NUM)|RW_RELEASE_EN)); + do{ + if((rtw_read32(adapter, REG_RXPKT_NUM)&RXDMA_IDLE)) { + DBG_871X_LEVEL(_drv_always_, "RX_DMA_IDLE is true\n"); + ret = _SUCCESS; + break; + } +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + else { + // If RX_DMA is not idle, receive one pkt from DMA + res = sdio_local_read(adapter, + SDIO_REG_RX0_REQ_LEN, 4, (u8*)&tmp); + len = le16_to_cpu(tmp); + DBG_871X_LEVEL(_drv_always_, "RX len:%d\n", len); + + if (len > 0) + res = RecvOnePkt(adapter, len); + else + DBG_871X_LEVEL(_drv_always_, "read length fail %d\n", len); + + DBG_871X_LEVEL(_drv_always_, "RecvOnePkt Result: %d\n", res); + } +#endif //CONFIG_SDIO_HCI || CONFIG_GSPI_HCI + }while(trycnt--); + + if(trycnt ==0) { + DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed...... \n"); + ret = _FAIL; + } + + return ret; +} + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +static u8 rtw_hal_enable_cpwm2(_adapter* adapter) +{ + u8 ret = 0; + int res = 0; + u32 tmp = 0; + + DBG_871X_LEVEL(_drv_always_, "%s\n", __func__); + + res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp); + if (!res) + DBG_871X_LEVEL(_drv_info_, "read SDIO_REG_HIMR: 0x%08x\n", tmp); + else + DBG_871X_LEVEL(_drv_info_, "sdio_local_read fail\n"); + + tmp = SDIO_HIMR_CPWM2_MSK; + + res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp); + + if (!res){ + res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp); + DBG_871X_LEVEL(_drv_info_, "read again SDIO_REG_HIMR: 0x%08x\n", tmp); + ret = _SUCCESS; + }else { + DBG_871X_LEVEL(_drv_info_, "sdio_local_write fail\n"); + ret = _FAIL; + } + + return ret; +} +#endif //CONFIG_SDIO_HCI, CONFIG_GSPI_HCI + +#ifdef CONFIG_GTK_OL +static void rtw_hal_fw_sync_cam_id(_adapter* adapter) +{ + struct security_priv *psecuritypriv = &adapter->securitypriv; + u8 null_addr[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + int cam_id; + u32 algorithm = 0; + u16 ctrl = 0; + u8 *addr; + u8 index = 0; + u8 get_key[16]; + + addr = get_bssid(&adapter->mlmepriv); + + if (addr == NULL) { + DBG_871X("%s: get bssid MAC addr fail!!\n", __func__); + return; + } + + do{ + cam_id = rtw_camid_search(adapter, addr, index); + if (cam_id == -1) { + DBG_871X("%s: cam_id: %d, key_id:%d\n", + __func__, cam_id, index); + } else if (rtw_camid_is_gk(adapter, cam_id) != _TRUE) { + DBG_871X("%s: cam_id: %d key_id(%d) is not GK\n", + __func__, cam_id, index); + } else { + read_cam(adapter ,cam_id, get_key); + algorithm = psecuritypriv->dot11PrivacyAlgrthm; + ctrl = BIT(15) | BIT6 |(algorithm << 2) | index; + write_cam(adapter, index, ctrl, addr, get_key); + ctrl = 0; + write_cam(adapter, cam_id, ctrl, null_addr, get_key); + } + index++; + }while(cam_id != -1); + + rtw_write8(adapter, REG_SECCFG, 0xcc); +} + +static void rtw_hal_update_gtk_offload_info(_adapter* adapter) +{ + struct security_priv *psecuritypriv = &adapter->securitypriv; + int cam_id; + u8 *addr; + u8 null_addr[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + u8 gtk_keyindex=0; + u8 get_key[16]; + u8 null_key[16]; + u8 index = 0; + u16 ctrl = 0; + u32 algorithm = 0; + + addr = get_bssid(&adapter->mlmepriv); + + if (addr == NULL) { + DBG_871X("%s: get bssid MAC addr fail!!\n", __func__); + return; + } + + _rtw_memset(null_key, 0, sizeof(null_key)); + + algorithm = psecuritypriv->dot11PrivacyAlgrthm; + + if(psecuritypriv->binstallKCK_KEK == _TRUE) { + //read gtk key index + gtk_keyindex = rtw_read8(adapter, 0x48c); + + do{ + cam_id = rtw_camid_search(adapter, addr, index); + if (cam_id == -1) { + DBG_871X("%s: cam_id: %d, key_id:%d\n", + __func__, cam_id, index); + } else if (read_phy_cam_is_gtk(adapter, cam_id) == + _FALSE){ + DBG_871X("%s: cam_id: %d, key_id:%d is not GK\n", + __func__, cam_id, index); + } else if (cam_id >= 4) { + DBG_871X("%s: cam_id(%d) is not in default key\n", + __func__, cam_id); + } else { + read_cam(adapter ,cam_id, get_key); + algorithm = psecuritypriv->dot11PrivacyAlgrthm; + ctrl = BIT(15) | BIT6 |(algorithm << 2) | index; + write_cam(adapter, cam_id+4, ctrl, + addr, get_key); + ctrl = 0; + write_cam(adapter, cam_id, ctrl, + null_addr, get_key); + } + + if (gtk_keyindex < 4 &&(index == gtk_keyindex)) { + psecuritypriv->dot118021XGrpKeyid = gtk_keyindex; + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, + get_key, 16); + + DBG_871X_LEVEL(_drv_always_, "GTK (%d) = 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + gtk_keyindex, + psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[0], + psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[1], + psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[2], + psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[3]); + } + index++; + }while(index < 4); + + rtw_write8(adapter, REG_SECCFG, 0x0c); +#ifdef CONFIG_GTK_OL_DBG + //if (gtk_keyindex != 5) + dump_cam_table(adapter); +#endif + } +} +#endif + +static void rtw_hal_update_tx_iv(_adapter* adapter) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + u64 iv_low = 0, iv_high = 0; + + // 3.1 read fw iv + iv_low = rtw_read32(adapter, REG_TXPKTBUF_IV_LOW); + //only low two bytes is PN, check AES_IV macro for detail + iv_low &= 0xffff; + iv_high = rtw_read32(adapter, REG_TXPKTBUF_IV_HIGH); + //get the real packet number + pwrctl->wowlan_fw_iv = iv_high << 16 | iv_low; + DBG_871X_LEVEL(_drv_always_, + "fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv); + //Update TX iv data. + rtw_set_sec_pn(adapter); +} + +static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type) +{ + struct hal_ops *pHalFunc = &adapter->HalFunc; + + u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0}; + u8 adopt = 1, check_period = 5; + u8 ret = _FAIL; + + DBG_871X("%s(): enable = %d\n", __func__, enable); + SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable); + SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt); + SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type); + SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period); + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_KEEP_ALIVE, + H2C_KEEP_ALIVE_CTRL_LEN, + u1H2CKeepAliveParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + + return ret; +} + +static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable) +{ + struct hal_ops *pHalFunc = &adapter->HalFunc; + u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN]={0}; + u8 adopt = 1, check_period = 10, trypkt_num = 0; + u8 ret = _FAIL; + + DBG_871X("%s(): enable = %d\n", __func__, enable); + SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable); + SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt); + SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period); + SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num); + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_DISCON_DECISION, + H2C_DISCON_DECISION_LEN, + u1H2CDisconDecisionParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + + return ret; +} + +static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable) +{ + struct hal_ops *pHalFunc = &adapter->HalFunc; + u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN]={0}; + u8 ret = _FAIL; + + DBG_871X("%s(): bFuncEn=%d\n", __func__, enable); + + SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable); + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_AP_OFFLOAD, + H2C_AP_OFFLOAD_LEN, + u1H2CAPOffloadCtrlParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + return ret; +} + +static u8 rtw_hal_set_ap_rsvdpage_loc_cmd(_adapter *adapter, + PRSVDPAGE_LOC rsvdpageloc) +{ + struct hal_ops *pHalFunc = &adapter->HalFunc; + u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0}; + u8 ret = _FAIL, header = 0; + + if (pHalFunc->fill_h2c_cmd == NULL) { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + return ret; + } + + header = rtw_read8(adapter, REG_BCNQ_BDNY); + + DBG_871X("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__, + rsvdpageloc->LocApOffloadBCN, + rsvdpageloc->LocProbeRsp, + header); + + SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm, + rsvdpageloc->LocApOffloadBCN + header); + + ret = pHalFunc->fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE, + H2C_BCN_RSVDPAGE_LEN, rsvdparm); + + if (ret == _FAIL) + DBG_871X("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__); + + _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm)); + + SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm, + rsvdpageloc->LocProbeRsp + header); + + ret = pHalFunc->fill_h2c_cmd(adapter, H2C_PROBERSP_RSVDPAGE, + H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm); + + if (ret == _FAIL) + DBG_871X("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__); + + return ret; +} + +u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable) +{ + struct security_priv *psecpriv = &adapter->securitypriv; + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); + struct hal_ops *pHalFunc = &adapter->HalFunc; + + u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN]={0}; + u8 discont_wake = 1, gpionum = 0, gpio_dur = 0; + u8 hw_unicast = 0, gpio_pulse_cnt = 0; + u8 sdio_wakeup_enable = 1; + u8 gpio_high_active = 0; //0: low active, 1: high active + u8 magic_pkt = 0; + u8 ret = _FAIL; + +#ifdef CONFIG_GPIO_WAKEUP + gpionum = WAKEUP_GPIO_IDX; + sdio_wakeup_enable = 0; + gpio_dur = 32; // 32*32us = 1024us +#ifdef CONFIG_GPIO_WAKEUP_LOW_ACTIVE + gpio_high_active = 0; +#else // !CONFIG_GPIO_WAKEUP_LOW_ACTIVE + gpio_high_active = 1; +#endif // !CONFIG_GPIO_WAKEUP_LOW_ACTIVE +#endif //CONFIG_GPIO_WAKEUP + + if (!ppwrpriv->wowlan_pno_enable) + magic_pkt = enable; + + if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_) + hw_unicast = 1; + else if (IS_HARDWARE_TYPE_8192E(adapter)) + hw_unicast = 1; + else + hw_unicast = 0; + + DBG_871X("%s: enable=%d GPIO=%d\n", __FUNCTION__, enable, gpionum); + + SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable); + SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, 0); + SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt); + SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast); + SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0); + SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active); +#ifndef CONFIG_GTK_OL + SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable); +#endif + SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake); + SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum); + SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable); + SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur); // (real)unit: 32us + SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, 1); +#ifdef CONFIG_PLATFORM_ARM_RK3188 + SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, 4); +#else + SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt); +#endif + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_WOWLAN, + H2C_WOWLAN_LEN, + u1H2CWoWlanCtrlParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + return ret; +} + +static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) +{ + struct hal_ops *pHalFunc = &adapter->HalFunc; + struct security_priv* psecuritypriv=&(adapter->securitypriv); + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); + u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN]={0}; + u8 ret = _FAIL, count = 0; + + DBG_871X("%s(): enable=%d\n", __func__, enable); + + if (!ppwrpriv->wowlan_pno_enable) { + SET_H2CCMD_REMOTE_WAKECTRL_ENABLE( + u1H2CRemoteWakeCtrlParm, enable); + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, 1); +#ifdef CONFIG_GTK_OL + if (psecuritypriv->binstallKCK_KEK == _TRUE && + psecuritypriv->dot11PrivacyAlgrthm == _AES_) { + SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, 1); + } else { + DBG_871X("no kck or security is not AES\n"); + SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, 0); + } +#endif //CONFIG_GTK_OL + + SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN( + u1H2CRemoteWakeCtrlParm, 1); + if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) || + (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) { + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( + u1H2CRemoteWakeCtrlParm, 0); + } else { + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( + u1H2CRemoteWakeCtrlParm, 1); + } + } +#ifdef CONFIG_PNO_SUPPORT + else { + SET_H2CCMD_REMOTE_WAKECTRL_ENABLE( + u1H2CRemoteWakeCtrlParm, enable); + SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, enable); + } +#endif + +#ifdef CONFIG_P2P_WOWLAN + if (_TRUE == ppwrpriv->wowlan_p2p_mode) + { + DBG_871X("P2P OFFLOAD ENABLE\n"); + SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm,1); + } + else + { + DBG_871X("P2P OFFLOAD DISABLE\n"); + SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm,0); + } +#endif //CONFIG_P2P_WOWLAN + + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_REMOTE_WAKE_CTRL, + H2C_REMOTE_WAKE_CTRL_LEN, + u1H2CRemoteWakeCtrlParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + return ret; +} + +static u8 rtw_hal_set_global_info_cmd(_adapter* adapter, u8 group_alg, u8 pairwise_alg) +{ + struct hal_ops *pHalFunc = &adapter->HalFunc; + u8 ret = _FAIL; + u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN]={0}; + + DBG_871X("%s(): group_alg=%d pairwise_alg=%d\n", + __func__, group_alg, pairwise_alg); + SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm, + pairwise_alg); + SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm, + group_alg); + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_AOAC_GLOBAL_INFO, + H2C_AOAC_GLOBAL_INFO_LEN, + u1H2CAOACGlobalInfoParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + + return ret; +} + +#ifdef CONFIG_PNO_SUPPORT +static u8 rtw_hal_set_scan_offload_info_cmd(_adapter* adapter, + PRSVDPAGE_LOC rsvdpageloc, u8 enable) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + struct hal_ops *pHalFunc = &adapter->HalFunc; + + u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN]={0}; + u8 res = 0, count = 0, ret = _FAIL; + + DBG_871X("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n", + __func__, rsvdpageloc->LocProbePacket, + rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo); + + SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable); + SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm, + rsvdpageloc->LocScanInfo); + SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm, + rsvdpageloc->LocProbePacket); + SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm, + rsvdpageloc->LocSSIDInfo); + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_D0_SCAN_OFFLOAD_INFO, + H2C_SCAN_OFFLOAD_CTRL_LEN, + u1H2CScanOffloadInfoParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + return ret; +} +#endif //CONFIG_PNO_SUPPORT + +void rtw_hal_set_fw_wow_related_cmd(_adapter* padapter, u8 enable) +{ + struct security_priv *psecpriv = &padapter->securitypriv; + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_info *psta = NULL; + u16 media_status_rpt; + u8 pkt_type = 0; + u8 ret = _SUCCESS; + + DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable); +_func_enter_; + + rtw_hal_set_wowlan_ctrl_cmd(padapter, enable); + + if (enable) { + rtw_hal_set_global_info_cmd(padapter, + psecpriv->dot118021XGrpPrivacy, + psecpriv->dot11PrivacyAlgrthm); + + if (!(ppwrpriv->wowlan_pno_enable)) { + rtw_hal_set_disconnect_decision_cmd(padapter, enable); +#ifdef CONFIG_ARP_KEEP_ALIVE + if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) || + (psecpriv->dot11PrivacyAlgrthm == _WEP104_)) + pkt_type = 0; + else + pkt_type = 1; +#else + pkt_type = 0; +#endif //CONFIG_ARP_KEEP_ALIVE + rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type); + } + rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); +#ifdef CONFIG_PNO_SUPPORT + rtw_hal_check_pno_enabled(padapter); +#endif //CONFIG_PNO_SUPPORT + } else { +#if 0 + { + u32 PageSize = 0; + rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize); + dump_TX_FIFO(padapter, 4, PageSize); + } +#endif + + rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); + rtw_hal_set_wowlan_ctrl_cmd(padapter, enable); + } +_func_exit_; + DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__); +} +#endif //CONFIG_WOWLAN + +#ifdef CONFIG_P2P_WOWLAN +static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) +{ + u8 *ssid_ie; + sint ssid_len_ori; + int len_diff = 0; + + ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len); + + //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); + + if(ssid_ie && ssid_len_ori>0) + { + switch(hidden_ssid_mode) + { + case 1: + { + u8 *next_ie = ssid_ie + 2 + ssid_len_ori; + u32 remain_len = 0; + + remain_len = ies_len -(next_ie-ies); + + ssid_ie[1] = 0; + _rtw_memcpy(ssid_ie+2, next_ie, remain_len); + len_diff -= ssid_len_ori; + + break; + } + case 2: + _rtw_memset(&ssid_ie[2], 0, ssid_len_ori); + break; + default: + break; + } + } + + return len_diff; +} + +static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength) +{ + //struct xmit_frame *pmgntframe; + //struct pkt_attrib *pattrib; + //unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned int rate_len; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + u32 pktlen; +//#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) +// _irqL irqL; +// struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +//#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#endif //CONFIG_P2P + + //for debug + u8 *dbgbuf = pframe; + u8 dbgbufLen = 0, index = 0; + + DBG_871X("%s\n", __FUNCTION__); +//#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) +// _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); +//#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); + + SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); + //pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_BEACON); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + + if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + //DBG_871X("ie len=%d\n", cur_network->IELength); +#ifdef CONFIG_P2P + // for P2P : Primary Device Type & Device Name + u32 wpsielen=0, insert_len=0; + u8 *wpsie=NULL; + wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen); + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0) + { + uint wps_offset, remainder_ielen; + u8 *premainder_ie, *pframe_wscie; + + wps_offset = (uint)(wpsie - cur_network->IEs); + + premainder_ie = wpsie + wpsielen; + + remainder_ielen = cur_network->IELength - wps_offset - wpsielen; + +#ifdef CONFIG_IOCTL_CFG80211 + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0) + { + _rtw_memcpy(pframe, cur_network->IEs, wps_offset); + pframe += wps_offset; + pktlen += wps_offset; + + _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len); + pframe += pmlmepriv->wps_beacon_ie_len; + pktlen += pmlmepriv->wps_beacon_ie_len; + + //copy remainder_ie to pframe + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pktlen += remainder_ielen; + } + else + { + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + pframe += cur_network->IELength; + pktlen += cur_network->IELength; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + pframe_wscie = pframe + wps_offset; + _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen); + pframe += (wps_offset + wpsielen); + pktlen += (wps_offset + wpsielen); + + //now pframe is end of wsc ie, insert Primary Device Type & Device Name + // Primary Device Type + // Type: + *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE ); + insert_len += 2; + + // Length: + *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 ); + insert_len += 2; + + // Value: + // Category ID + *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + insert_len += 2; + + // OUI + *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI ); + insert_len += 4; + + // Sub Category ID + *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + insert_len += 2; + + + // Device Name + // Type: + *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); + insert_len += 2; + + // Length: + *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len ); + insert_len += 2; + + // Value: + _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len ); + insert_len += pwdinfo->device_name_len; + + + //update wsc ie length + *(pframe_wscie+1) = (wpsielen -2) + insert_len; + + //pframe move to end + pframe+=insert_len; + pktlen += insert_len; + + //copy remainder_ie to pframe + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pktlen += remainder_ielen; + } + } + else +#endif //CONFIG_P2P + { + int len_diff; + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + len_diff = update_hidden_ssid( + pframe+_BEACON_IE_OFFSET_ + , cur_network->IELength-_BEACON_IE_OFFSET_ + , pmlmeinfo->hidden_ssid_mode + ); + pframe += (cur_network->IELength+len_diff); + pktlen += (cur_network->IELength+len_diff); + } +#if 0 + { + u8 *wps_ie; + uint wps_ielen; + u8 sr = 0; + wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_, + pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen); + if (wps_ie && wps_ielen>0) { + rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL); + } + if (sr != 0) + set_fwstate(pmlmepriv, WIFI_UNDER_WPS); + else + _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS); + } +#endif +#ifdef CONFIG_P2P + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + u32 len; +#ifdef CONFIG_IOCTL_CFG80211 + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + len = pmlmepriv->p2p_beacon_ie_len; + if(pmlmepriv->p2p_beacon_ie && len>0) + _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len); + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + len = build_beacon_p2p_ie(pwdinfo, pframe); + } + + pframe += len; + pktlen += len; +#ifdef CONFIG_WFD +#ifdef CONFIG_IOCTL_CFG80211 + if(_TRUE == pwdinfo->wfd_info->wfd_enable) +#endif //CONFIG_IOCTL_CFG80211 + { + len = build_beacon_wfd_ie( pwdinfo, pframe ); + } +#ifdef CONFIG_IOCTL_CFG80211 + else + { + len = 0; + if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0) + { + len = pmlmepriv->wfd_beacon_ie_len; + _rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len); + } + } +#endif //CONFIG_IOCTL_CFG80211 + pframe += len; + pktlen += len; +#endif //CONFIG_WFD + } +#endif //CONFIG_P2P + + goto _issue_bcn; + + } + + //below for ad-hoc mode + + //timestamp will be inserted by hardware + pframe += 8; + pktlen += 8; + + // beacon interval: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pktlen += 2; + + // capability info: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pktlen += 2; + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen); + + // supported rates... + rate_len = rtw_get_rateset_len(cur_network->SupportedRates); + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen); + + //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) + { + u8 erpinfo=0; + u32 ATIMWindow; + // IBSS Parameter Set... + //ATIMWindow = cur->Configuration.ATIMWindow; + ATIMWindow = 0; + pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen); + + //ERP IE + pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen); + } + + + // EXTERNDED SUPPORTED RATE + if (rate_len > 8) + { + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen); + } + + + //todo:HT for adhoc + +_issue_bcn: + +//#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) +// pmlmepriv->update_bcn = _FALSE; +// +// _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); +//#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + + *pLength = pktlen; +#if 0 + // printf dbg msg + dbgbufLen = pktlen; + DBG_871X("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n"); + + for(index=0;indexxmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + u16 beacon_interval = 100; + u16 capInfo = 0; + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + u8 wpsie[255] = { 0x00 }; + u32 wpsielen = 0, p2pielen = 0; + u32 pktlen; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD +#ifdef CONFIG_INTEL_WIDI + u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 }; +#endif //CONFIG_INTEL_WIDI + + //for debug + u8 *dbgbuf = pframe; + u8 dbgbufLen = 0, index = 0; + + DBG_871X("%s\n", __FUNCTION__); + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + mac = myid(&(padapter->eeprompriv)); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + //DA filled by FW + _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN); + + // Use the device address for BSSID field. + _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetFrameSubType(fctrl, WIFI_PROBERSP); + + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pframe += pktlen; + + + //timestamp will be inserted by hardware + pframe += 8; + pktlen += 8; + + // beacon interval: 2 bytes + _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2); + pframe += 2; + pktlen += 2; + + // capability info: 2 bytes + // ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) + capInfo |= cap_ShortPremble; + capInfo |= cap_ShortSlot; + + _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2); + pframe += 2; + pktlen += 2; + + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen); + + // supported rates... + // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen); + +#ifdef CONFIG_IOCTL_CFG80211 + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL ) + { + //WPS IE + _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len); + pktlen += pmlmepriv->wps_probe_resp_ie_len; + pframe += pmlmepriv->wps_probe_resp_ie_len; + + //P2P IE + _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len); + pktlen += pmlmepriv->p2p_probe_resp_ie_len; + pframe += pmlmepriv->p2p_probe_resp_ie_len; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + + // Todo: WPS IE + // Noted by Albert 20100907 + // According to the WPS specification, all the WPS attribute is presented by Big Endian. + + wpsielen = 0; + // WPS OUI + *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); + wpsielen += 4; + + // WPS version + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 ); + wpsielen += 2; + + // Value: + wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0 + +#ifdef CONFIG_INTEL_WIDI + // Commented by Kurt + // Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. + if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE + || pmlmepriv->num_p2p_sdt != 0 ) + { + //Sec dev type + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 ); + wpsielen += 2; + + // Value: + // Category ID + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS ); + wpsielen += 2; + + // OUI + *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI ); + wpsielen += 4; + + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK ); + wpsielen += 2; + + if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE ) + { + // Vendor Extension + _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN ); + wpsielen += L2SDTA_SERVICE_VE_LEN; + } + } +#endif //CONFIG_INTEL_WIDI + + // WiFi Simple Config State + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 ); + wpsielen += 2; + + // Value: + wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; // Not Configured. + + // Response Type + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 ); + wpsielen += 2; + + // Value: + wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X; + + // UUID-E + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 ); + wpsielen += 2; + + // Value: + if (pwdinfo->external_uuid == 0) { + _rtw_memset( wpsie + wpsielen, 0x0, 16 ); + _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN ); + } else { + _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 ); + } + wpsielen += 0x10; + + // Manufacturer + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 ); + wpsielen += 2; + + // Value: + _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 ); + wpsielen += 7; + + // Model Name + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 ); + wpsielen += 2; + + // Value: + _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 ); + wpsielen += 6; + + // Model Number + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 ); + wpsielen += 2; + + // Value: + wpsie[ wpsielen++ ] = 0x31; // character 1 + + // Serial Number + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN ); + wpsielen += 2; + + // Value: + _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN ); + wpsielen += ETH_ALEN; + + // Primary Device Type + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 ); + wpsielen += 2; + + // Value: + // Category ID + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + wpsielen += 2; + + // OUI + *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI ); + wpsielen += 4; + + // Sub Category ID + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + wpsielen += 2; + + // Device Name + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len ); + wpsielen += 2; + + // Value: + _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len ); + wpsielen += pwdinfo->device_name_len; + + // Config Method + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); + wpsielen += 2; + + // Value: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm ); + wpsielen += 2; + + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen ); + + + p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe); + pframe += p2pielen; + pktlen += p2pielen; + } + +#ifdef CONFIG_WFD +#ifdef CONFIG_IOCTL_CFG80211 + if ( _TRUE == pwdinfo->wfd_info->wfd_enable ) +#endif //CONFIG_IOCTL_CFG80211 + { + wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0); + pframe += wfdielen; + pktlen += wfdielen; + } +#ifdef CONFIG_IOCTL_CFG80211 + else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0) + { + //WFD IE + _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len); + pktlen += pmlmepriv->wfd_probe_resp_ie_len; + pframe += pmlmepriv->wfd_probe_resp_ie_len; + } +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_WFD + + *pLength = pktlen; + +#if 0 + // printf dbg msg + dbgbufLen = pktlen; + DBG_871X("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n"); + + for(index=0;indexxmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo); + //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD + + //for debug + u8 *dbgbuf = pframe; + u8 dbgbufLen = 0, index = 0; + + DBG_871X( "%s\n", __FUNCTION__); + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + //RA, filled by FW + _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetFrameSubType(pframe, WIFI_ACTION); + + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pframe += pktlen; + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen)); + + //dialog token, filled by FW + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen)); + + _rtw_memset( wpsie, 0x00, 255 ); + wpsielen = 0; + + // WPS Section + wpsielen = 0; + // WPS OUI + *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); + wpsielen += 4; + + // WPS version + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 ); + wpsielen += 2; + + // Value: + wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0 + + // Device Password ID + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); + wpsielen += 2; + + // Value: + if ( wps_devicepassword_id == WPS_DPID_USER_SPEC ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); + } + else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC ); + } + else + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC ); + } + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen ); + + + // P2P IE Section. + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20100908 + // According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes + // 1. Status + // 2. P2P Capability + // 3. Group Owner Intent + // 4. Configuration Timeout + // 5. Operating Channel + // 6. Intended P2P Interface Address + // 7. Channel List + // 8. Device Info + // 9. Group ID ( Only GO ) + + + // ToDo: + + // P2P Status + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_STATUS; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 ); + p2pielen += 2; + + // Value, filled by FW + p2pie[ p2pielen++ ] = 1; + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) ) + { + // Commented by Albert 2011/03/08 + // According to the P2P specification + // if the sending device will be client, the P2P Capability should be reserved of group negotation response frame + p2pie[ p2pielen++ ] = 0; + } + else + { + // Be group owner or meet the error case + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + } + + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + { + p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP; + } + else + { + p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN; + } + + // Group Owner Intent + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 ); + p2pielen += 2; + + // Value: + if ( pwdinfo->peer_intent & 0x01 ) + { + // Peer's tie breaker bit is 1, our tie breaker bit should be 0 + p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 ); + } + else + { + // Peer's tie breaker bit is 0, our tie breaker bit should be 1 + p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) ); + } + + + // Configuration Timeout + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO + p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client + + // Operating Channel + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 ); + p2pielen += 2; + + // Value: + // Country String + p2pie[ p2pielen++ ] = 'X'; + p2pie[ p2pielen++ ] = 'X'; + + // The third byte should be set to 0x04. + // Described in the "Operating Channel Attribute" section. + p2pie[ p2pielen++ ] = 0x04; + + // Operating Class + if ( pwdinfo->operating_channel <= 14 ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x51; + } + else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x73; + } + else + { + // Operating Class + p2pie[ p2pielen++ ] = 0x7c; + } + + // Channel Number + p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number + + // Intended P2P Interface Address + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN ); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN ); + p2pielen += ETH_ALEN; + + // Channel List + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST; + + // Country String(3) + // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) + // + number of channels in all classes + len_channellist_attr = 3 + + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes + + get_reg_classes_full_count(pmlmeext->channel_list); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 ); + } + else + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr ); + } +#else + + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr ); + + #endif + p2pielen += 2; + + // Value: + // Country String + p2pie[ p2pielen++ ] = 'X'; + p2pie[ p2pielen++ ] = 'X'; + + // The third byte should be set to 0x04. + // Described in the "Operating Channel Attribute" section. + p2pie[ p2pielen++ ] = 0x04; + + // Channel Entry List + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + // Operating Class + if ( pbuddy_mlmeext->cur_channel > 14 ) + { + if ( pbuddy_mlmeext->cur_channel >= 149 ) + { + p2pie[ p2pielen++ ] = 0x7c; + } + else + { + p2pie[ p2pielen++ ] = 0x73; + } + } + else + { + p2pie[ p2pielen++ ] = 0x51; + } + + // Number of Channels + // Just support 1 channel and this channel is AP's channel + p2pie[ p2pielen++ ] = 1; + + // Channel List + p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel; + } + else + { + int i, j; + for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { + // Operating Class + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; + + // Number of Channels + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; + + // Channel List + for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; + } + } + } +#else // CONFIG_CONCURRENT_MODE + { + int i, j; + for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { + // Operating Class + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; + + // Number of Channels + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; + + // Channel List + for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; + } + } + } +#endif // CONFIG_CONCURRENT_MODE + + + // Device Info + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO; + + // Length: + // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) + // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len ); + p2pielen += 2; + + // Value: + // P2P Device Address + _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN ); + p2pielen += ETH_ALEN; + + // Config Method + // This field should be big endian. Noted by P2P specification. + + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm ); + + p2pielen += 2; + + // Primary Device Type + // Category ID + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + p2pielen += 2; + + // OUI + *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + p2pielen += 4; + + // Sub Category ID + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + p2pielen += 2; + + // Number of Secondary Device Types + p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List + + // Device Name + // Type: + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); + p2pielen += 2; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len ); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len ); + p2pielen += pwdinfo->device_name_len; + + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) ) + { + // Group ID Attribute + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen ); + p2pielen += 2; + + // Value: + // p2P Device Address + _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN ); + p2pielen += ETH_ALEN; + + // SSID + _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen ); + p2pielen += pwdinfo->nego_ssidlen; + + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pktlen += wfdielen; +#endif //CONFIG_WFD + + *pLength = pktlen; +#if 0 + // printf dbg msg + dbgbufLen = pktlen; + DBG_871X("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n"); + + for(index=0;indexpbuddy_adapter; + struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD + + //struct xmit_frame *pmgntframe; + //struct pkt_attrib *pattrib; + //unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo); + + //for debug + u8 *dbgbuf = pframe; + u8 dbgbufLen = 0, index = 0; + + + DBG_871X( "%s\n", __FUNCTION__); + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + //RA fill by FW + _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + + //BSSID fill by FW + _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetFrameSubType(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen)); + + //dialog token, filled by FW + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen)); + + // P2P IE Section. + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20101005 + // According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes + // 1. Status + // 2. Configuration Timeout + // 3. Operating Channel ( Only GO ) + // 4. P2P Group BSSID ( Only GO ) + // 5. Channel List + + // P2P Status + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_STATUS; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 ); + p2pielen += 2; + + // Value: filled by FW, defult value is FAIL INFO UNAVAILABLE + p2pie[ p2pielen++ ] = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + + // Configuration Timeout + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO + p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client + + // due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed +#if 0 + if( status_code == P2P_STATUS_SUCCESS ) + { + if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) ) + { + // The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO + // In this case, the P2P Invitation response frame should carry the two more P2P attributes. + // First one is operating channel attribute. + // Second one is P2P Group BSSID attribute. + + // Operating Channel + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 ); + p2pielen += 2; + + // Value: + // Country String + p2pie[ p2pielen++ ] = 'X'; + p2pie[ p2pielen++ ] = 'X'; + + // The third byte should be set to 0x04. + // Described in the "Operating Channel Attribute" section. + p2pie[ p2pielen++ ] = 0x04; + + // Operating Class + p2pie[ p2pielen++ ] = 0x51; // Copy from SD7 + + // Channel Number + p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number + + + // P2P Group BSSID + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN ); + p2pielen += 2; + + // Value: + // P2P Device Address for GO + _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN ); + p2pielen += ETH_ALEN; + + } + + // Channel List + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST; + + // Length: + // Country String(3) + // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) + // + number of channels in all classes + len_channellist_attr = 3 + + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes + + get_reg_classes_full_count(pmlmeext->channel_list); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 ); + } + else + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr ); + } +#else + + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr ); + +#endif + p2pielen += 2; + + // Value: + // Country String + p2pie[ p2pielen++ ] = 'X'; + p2pie[ p2pielen++ ] = 'X'; + + // The third byte should be set to 0x04. + // Described in the "Operating Channel Attribute" section. + p2pie[ p2pielen++ ] = 0x04; + + // Channel Entry List +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + // Operating Class + if ( pbuddy_mlmeext->cur_channel > 14 ) + { + if ( pbuddy_mlmeext->cur_channel >= 149 ) + { + p2pie[ p2pielen++ ] = 0x7c; + } + else + { + p2pie[ p2pielen++ ] = 0x73; + } + } + else + { + p2pie[ p2pielen++ ] = 0x51; + } + + // Number of Channels + // Just support 1 channel and this channel is AP's channel + p2pie[ p2pielen++ ] = 1; + + // Channel List + p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel; + } + else + { + int i, j; + for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { + // Operating Class + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; + + // Number of Channels + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; + + // Channel List + for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; + } + } + } +#else // CONFIG_CONCURRENT_MODE + { + int i, j; + for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { + // Operating Class + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; + + // Number of Channels + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; + + // Channel List + for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { + p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; + } + } + } +#endif // CONFIG_CONCURRENT_MODE + } +#endif + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pktlen += wfdielen; +#endif //CONFIG_WFD + + *pLength = pktlen; + +#if 0 + // printf dbg msg + dbgbufLen = pktlen; + DBG_871X("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n"); + + for(index=0;indexxmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo); + + //for debug + u8 *dbgbuf = pframe; + u8 dbgbufLen = 0, index = 0; + + DBG_871X( "%s\n", __FUNCTION__); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + //RA filled by FW + _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + + SetSeqNum(pwlanhdr,0); + SetFrameSubType(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen)); + //dialog token, filled by FW + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen)); + + wpsielen = 0; + // WPS OUI + //*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(wpsie, WPSOUI); + wpsielen += 4; + +#if 0 + // WPS version + // Type: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 ); + wpsielen += 2; + + // Length: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 ); + wpsielen += 2; + + // Value: + wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0 +#endif + + // Config Method + // Type: + //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); + RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD); + wpsielen += 2; + + // Length: + //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); + RTW_PUT_BE16(wpsie + wpsielen, 0x0002); + wpsielen += 2; + + // Value: filled by FW, default value is PBC + //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); + RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON); + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pktlen += wfdielen; +#endif //CONFIG_WFD + + *pLength = pktlen; + + // printf dbg msg +#if 0 + dbgbufLen = pktlen; + DBG_871X("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n"); + + for(index=0;indexHalFunc; + u8 ret = _FAIL; + + DBG_871X("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n", + rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp, + rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp, + rsvdpageloc->LocPDRsp); + + SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp); + SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll); + SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData); + SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull); + SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull); + + //FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_P2P_OFFLOAD_RSVD_PAGE, + H2C_P2PRSVDPAGE_LOC_LEN, + u1H2CP2PRsvdPageParm); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + + return ret; +} + +u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter* adapter) +{ + + u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0}; + struct wifidirect_info *pwdinfo = &(adapter->wdinfo); + struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd; + struct hal_ops *pHalFunc = &adapter->HalFunc; + u8 ret = _FAIL; + + _rtw_memset(p2p_wowlan_offload,0 ,sizeof(struct P2P_WoWlan_Offload_t)); + DBG_871X("%s\n",__func__); + switch(pwdinfo->role) + { + case P2P_ROLE_DEVICE: + DBG_871X("P2P_ROLE_DEVICE\n"); + p2p_wowlan_offload->role = 0; + break; + case P2P_ROLE_CLIENT: + DBG_871X("P2P_ROLE_CLIENT\n"); + p2p_wowlan_offload->role = 1; + break; + case P2P_ROLE_GO: + DBG_871X("P2P_ROLE_GO\n"); + p2p_wowlan_offload->role = 2; + break; + default: + DBG_871X("P2P_ROLE_DISABLE\n"); + break; + } + p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm>>8; + p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm; + offload_cmd = (u8*)p2p_wowlan_offload; + DBG_871X("p2p_wowlan_offload: %x:%x:%x\n",offload_cmd[0],offload_cmd[1],offload_cmd[2]); + + if (pHalFunc->fill_h2c_cmd != NULL) { + ret = pHalFunc->fill_h2c_cmd(adapter, + H2C_P2P_OFFLOAD, + H2C_P2P_OFFLOAD_LEN, + offload_cmd); + } else { + DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__); + ret = _FAIL; + } + + return ret; + + //FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); +} +#endif //CONFIG_P2P_WOWLAN + +static void rtw_hal_construct_beacon(_adapter *padapter, + u8 *pframe, u32 *pLength) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 rate_len, pktlen; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + + //DBG_871X("%s\n", __FUNCTION__); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); + + SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); + //pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_BEACON); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + + //timestamp will be inserted by hardware + pframe += 8; + pktlen += 8; + + // beacon interval: 2 bytes + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pktlen += 2; + + // capability info: 2 bytes + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pktlen += 2; + + if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + //DBG_871X("ie len=%d\n", cur_network->IELength); + pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs); + _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen); + + goto _ConstructBeacon; + } + + //below for ad-hoc mode + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen); + + // supported rates... + rate_len = rtw_get_rateset_len(cur_network->SupportedRates); + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen); + + if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) + { + u32 ATIMWindow; + // IBSS Parameter Set... + //ATIMWindow = cur->Configuration.ATIMWindow; + ATIMWindow = 0; + pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen); + } + + + //todo: ERP IE + + + // EXTERNDED SUPPORTED RATE + if (rate_len > 8) + { + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen); + } + + + //todo:HT for adhoc + +_ConstructBeacon: + + if ((pktlen + TXDESC_SIZE) > 512) + { + DBG_871X("beacon frame too large\n"); + return; + } + + *pLength = pktlen; + + //DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen); + +} + +static void rtw_hal_construct_PSPoll(_adapter *padapter, + u8 *pframe, u32 *pLength) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //DBG_871X("%s\n", __FUNCTION__); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + // Frame control. + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + SetPwrMgt(fctrl); + SetFrameSubType(pframe, WIFI_PSPOLL); + + // AID. + SetDuration(pframe, (pmlmeinfo->aid | 0xc000)); + + // BSSID. + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + // TA. + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + + *pLength = 16; +} + +static void rtw_hal_construct_NullFunctionData( + PADAPTER padapter, + u8 *pframe, + u32 *pLength, + u8 *StaAddr, + u8 bQoS, + u8 AC, + u8 bEosp, + u8 bForcePowerSave) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + + //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave); + + pwlanhdr = (struct rtw_ieee80211_hdr*)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + if (bForcePowerSave) + { + SetPwrMgt(fctrl); + } + + switch(cur_network->network.InfrastructureMode) + { + case Ndis802_11Infrastructure: + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN); + break; + case Ndis802_11APMode: + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + break; + case Ndis802_11IBSS: + default: + _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + break; + } + + SetSeqNum(pwlanhdr, 0); + + if (bQoS == _TRUE) { + struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr; + + SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); + + pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe; + SetPriority(&pwlanqoshdr->qc, AC); + SetEOSP(&pwlanqoshdr->qc, bEosp); + + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); + } else { + SetFrameSubType(pframe, WIFI_DATA_NULL); + + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + } + + *pLength = pktlen; +} + +#ifdef CONFIG_WOWLAN +// +// Description: +// Construct the ARP response packet to support ARP offload. +// +static void rtw_hal_construct_ARPRsp( + PADAPTER padapter, + u8 *pframe, + u32 *pLength, + u8 *pIPAddress + ) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06}; + u8 *pARPRspPkt = pframe; + //for TKIP Cal MIC + u8 *payload = pframe; + u8 EncryptionHeadOverhead = 0; + //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave); + + pwlanhdr = (struct rtw_ieee80211_hdr*)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + //------------------------------------------------------------------------- + // MAC Header. + //------------------------------------------------------------------------- + SetFrameType(fctrl, WIFI_DATA); + //SetFrameSubType(fctrl, 0); + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetDuration(pwlanhdr, 0); + //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); + //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); + //SET_80211_HDR_TO_DS(pARPRspPkt, 1); + //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); + //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); + //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); + + //SET_80211_HDR_DURATION(pARPRspPkt, 0); + //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif + default: + EncryptionHeadOverhead = 0; + } + + if(EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + //SET_80211_HDR_WEP(pARPRspPkt, 1); //Suggested by CCW. + SetPrivacy(fctrl); + } + + //------------------------------------------------------------------------- + // Frame Body. + //------------------------------------------------------------------------- + pARPRspPkt = (u8*)(pframe+ *pLength); + payload = pARPRspPkt; //Get Payload pointer + // LLC header + _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8); + *pLength += 8; + + // ARP element + pARPRspPkt += 8; + SET_ARP_PKT_HW(pARPRspPkt, 0x0100); + SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); // IP protocol + SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6); + SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4); + SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response + SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv))); + SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress); +#ifdef CONFIG_ARP_KEEP_ALIVE + if (rtw_gw_addr_query(padapter)==0) { + SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr); + SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip); + } + else +#endif + { + SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, + get_my_bssid(&(pmlmeinfo->network))); + SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, + pIPAddress); + DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, + MAC_ARG(get_my_bssid(&(pmlmeinfo->network)))); + DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, + IP_ARG(pIPAddress)); + } + + *pLength += 28; + + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { + u8 mic[8]; + struct mic_data micdata; + struct sta_info *psta = NULL; + u8 priority[4]={0x0,0x0,0x0,0x0}; + u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; + + DBG_871X("%s(): Add MIC\n",__FUNCTION__); + + psta = rtw_get_stainfo(&padapter->stapriv, + get_my_bssid(&(pmlmeinfo->network))); + if (psta != NULL) { + if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0], + null_key, 16)==_TRUE) { + DBG_871X("%s(): STA dot11tkiptxmickey==0\n", + __func__); + } + //start to calculate the mic code + rtw_secmicsetkey(&micdata, + &psta->dot11tkiptxmickey.skey[0]); + } + + rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); //DA + + rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA + + priority[0]=0; + + rtw_secmicappend(&micdata, &priority[0], 4); + + rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28 + + rtw_secgetmic(&micdata,&(mic[0])); + + pARPRspPkt += 28; + _rtw_memcpy(pARPRspPkt, &(mic[0]),8); + + *pLength += 8; + } +} + +#ifdef CONFIG_PNO_SUPPORT +static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe, + u32 *pLength, pno_ssid_t *ssid) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + unsigned char *mac; + unsigned char bssrate[NumRates]; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + int bssrate_len = 0; + u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + mac = myid(&(padapter->eeprompriv)); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN); + + _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetFrameSubType(pframe, WIFI_PROBEREQ); + + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pframe += pktlen; + + if (ssid == NULL) { + pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen); + } else { + //DBG_871X("%s len:%d\n", ssid->SSID, ssid->SSID_len); + pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen); + } + + get_rate_set(padapter, bssrate, &bssrate_len); + + if (bssrate_len > 8) + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen); + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen); + } + else + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen); + } + + *pLength = pktlen; +} + +static void rtw_hal_construct_PNO_info(_adapter *padapter, + u8 *pframe, u32*pLength) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + + u8 *pPnoInfoPkt = pframe; + pPnoInfoPkt = (u8*)(pframe+ *pLength); + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1); + + *pLength+=1; + pPnoInfoPkt += 1; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1); + + *pLength+=3; + pPnoInfoPkt += 3; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1); + + *pLength+=4; + pPnoInfoPkt += 4; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4); + + *pLength+=4; + pPnoInfoPkt += 4; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4); + + *pLength+=4; + pPnoInfoPkt += 4; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, + MAX_PNO_LIST_COUNT); + + *pLength+=MAX_PNO_LIST_COUNT; + pPnoInfoPkt += MAX_PNO_LIST_COUNT; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, + MAX_PNO_LIST_COUNT); + + *pLength+=MAX_PNO_LIST_COUNT; + pPnoInfoPkt += MAX_PNO_LIST_COUNT; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, + MAX_PNO_LIST_COUNT); + + *pLength+=MAX_PNO_LIST_COUNT; + pPnoInfoPkt += MAX_PNO_LIST_COUNT; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, + MAX_HIDDEN_AP); + + *pLength+=MAX_HIDDEN_AP; + pPnoInfoPkt += MAX_HIDDEN_AP; +} + +static void rtw_hal_construct_ssid_list(_adapter *padapter, + u8 *pframe, u32 *pLength) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + u8 *pSSIDListPkt = pframe; + int i; + + pSSIDListPkt = (u8*)(pframe+ *pLength); + + for(i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) { + _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID, + pwrctl->pnlo_info->ssid_length[i]); + + *pLength += WLAN_SSID_MAXLEN; + pSSIDListPkt += WLAN_SSID_MAXLEN; + } +} + +static void rtw_hal_construct_scan_info(_adapter *padapter, + u8 *pframe, u32 *pLength) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + u8 *pScanInfoPkt = pframe; + int i; + + pScanInfoPkt = (u8*)(pframe+ *pLength); + + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1); + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1); + + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1); + + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1); + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1); + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1); + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1); + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1); + + *pLength+=1; + pScanInfoPkt += 1; + _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8); + + *pLength+=8; + pScanInfoPkt += 8; + + for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i ++) { + _rtw_memcpy(pScanInfoPkt, + &pwrctl->pscan_info->ssid_channel_info[i], 4); + *pLength+=4; + pScanInfoPkt += 4; + } +} +#endif //CONFIG_PNO_SUPPORT + +#ifdef CONFIG_GTK_OL +static void rtw_hal_construct_GTKRsp( + PADAPTER padapter, + u8 *pframe, + u32 *pLength + ) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E}; + static u8 GTKbody_a[11] ={0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B}; + u8 *pGTKRspPkt = pframe; + u8 EncryptionHeadOverhead = 0; + //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave); + + pwlanhdr = (struct rtw_ieee80211_hdr*)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + //------------------------------------------------------------------------- + // MAC Header. + //------------------------------------------------------------------------- + SetFrameType(fctrl, WIFI_DATA); + //SetFrameSubType(fctrl, 0); + SetToDs(fctrl); + + _rtw_memcpy(pwlanhdr->addr1, + get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + _rtw_memcpy(pwlanhdr->addr2, + myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pwlanhdr->addr3, + get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetDuration(pwlanhdr, 0); + +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif //CONFIG_WAPI_SUPPORT + + //------------------------------------------------------------------------- + // Security Header: leave space for it if necessary. + //------------------------------------------------------------------------- + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif //CONFIG_WAPI_SUPPORT + default: + EncryptionHeadOverhead = 0; + } + + if (EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + //SET_80211_HDR_WEP(pGTKRspPkt, 1); //Suggested by CCW. + //GTK's privacy bit is done by FW + //SetPrivacy(fctrl); + } + //------------------------------------------------------------------------- + // Frame Body. + //------------------------------------------------------------------------- + pGTKRspPkt = (u8*)(pframe+ *pLength); + // LLC header + _rtw_memcpy(pGTKRspPkt, LLCHeader, 8); + *pLength += 8; + + // GTK element + pGTKRspPkt += 8; + + //GTK frame body after LLC, part 1 + _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11); + *pLength += 11; + pGTKRspPkt += 11; + //GTK frame body after LLC, part 2 + _rtw_memset(&(pframe[*pLength]), 0, 88); + *pLength += 88; + pGTKRspPkt += 88; + +} +#endif //CONFIG_GTK_OL + + +// +// Description: Fill the reserved packets that FW will use to RSVD page. +// Now we just send 4 types packet to rsvd page. +// (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. +// Input: +// finished - FALSE:At the first time we will send all the packets as a large packet to Hw, +// so we need to set the packet length to total lengh. +// TRUE: At the second time, we should send the first packet (default:beacon) +// to Hw again and set the lengh in descriptor to the real beacon lengh. +// 2009.10.15 by tynli. +// +//Page Size = 128: 8188e, 8723a/b, 8192c/d, +//Page Size = 256: 8192e, 8821a +//Page Size = 512: 8812a +void rtw_hal_set_fw_rsvd_page(_adapter* adapter, bool finished) +{ + PHAL_DATA_TYPE pHalData; + struct xmit_frame *pcmdframe; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv; + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + struct pwrctrl_priv *pwrctl; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct hal_ops *pHalFunc = &adapter->HalFunc; + u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0; + u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0; + u32 ProbeReqLength = 0, NullFunctionDataLength = 0; + u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET; + u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0; + u8 *ReservedPagePacket; + u16 BufIndex = 0; + u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0; + RSVDPAGE_LOC RsvdPageLoc; +#ifdef CONFIG_WOWLAN + u32 ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0; + u32 SSIDLegnth = 0; + struct security_priv *psecuritypriv = &adapter->securitypriv; //added by xx + u8 currentip[4]; + u8 cur_dot11txpn[8]; +#ifdef CONFIG_GTK_OL + struct sta_priv *pstapriv = &adapter->stapriv; + struct sta_info * psta; + u8 kek[RTW_KEK_LEN]; + u8 kck[RTW_KCK_LEN]; +#endif //CONFIG_GTK_OL +#ifdef CONFIG_PNO_SUPPORT + int index; + u8 ssid_num; +#endif //CONFIG_PNO_SUPPORT +#endif +#ifdef DBG_CONFIG_ERROR_DETECT + struct sreset_priv *psrtpriv; +#endif // DBG_CONFIG_ERROR_DETECT + +#ifdef CONFIG_P2P_WOWLAN + u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0, P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0; +#endif + + pHalData = GET_HAL_DATA(adapter); +#ifdef DBG_CONFIG_ERROR_DETECT + psrtpriv = &pHalData->srestpriv; +#endif + pxmitpriv = &adapter->xmitpriv; + pmlmeext = &adapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + pwrctl = adapter_to_pwrctl(adapter); + + rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize); + DBG_871X("%s PAGE_SIZE: %d\n", __func__, PageSize); + if (pHalFunc->hal_get_tx_buff_rsvd_page_num != NULL) { + RsvdPageNum = + pHalFunc->hal_get_tx_buff_rsvd_page_num(adapter, _TRUE); + DBG_871X("%s RsvdPageNUm: %d\n", __func__, RsvdPageNum); + } else { + DBG_871X("[Error]: %s, missing tx_buff_rsvd_page_num func!!\n", + __func__); + } + + MaxRsvdPageBufSize = RsvdPageNum*PageSize; + + pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv); + if (pcmdframe == NULL) { + DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__); + return; + } + + ReservedPagePacket = pcmdframe->buf_addr; + _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC)); + + //beacon * 2 pages + BufIndex = TxDescOffset; + rtw_hal_construct_beacon(adapter, + &ReservedPagePacket[BufIndex], &BeaconLength); + + // When we count the first page size, we need to reserve description size for the RSVD + // packet, it will be filled in front of the packet in TXPKTBUF. + CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength); + //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware + if (CurtPktPageNum == 1) + CurtPktPageNum += 1; + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //ps-poll * 1 page + RsvdPageLoc.LocPsPoll = TotalPageNum; + DBG_871X("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll); + rtw_hal_construct_PSPoll(adapter, + &ReservedPagePacket[BufIndex], &PSPollLength); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + PSPollLength, _TRUE, _FALSE, _FALSE); + + CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + +#ifdef CONFIG_BT_COEXIST + //BT Qos null data * 1 page + RsvdPageLoc.LocBTQosNull = TotalPageNum; + DBG_871X("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull); + rtw_hal_construct_NullFunctionData( + adapter, + &ReservedPagePacket[BufIndex], + &BTQosNullLength, + get_my_bssid(&pmlmeinfo->network), + _TRUE, 0, 0, _FALSE); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + BTQosNullLength, _FALSE, _TRUE, _FALSE); + + CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); +#endif //CONFIG_BT_COEXIT + + //null data * 1 page + RsvdPageLoc.LocNullData = TotalPageNum; + DBG_871X("LocNullData: %d\n", RsvdPageLoc.LocNullData); + rtw_hal_construct_NullFunctionData( + adapter, + &ReservedPagePacket[BufIndex], + &NullDataLength, + get_my_bssid(&pmlmeinfo->network), + _FALSE, 0, 0, _FALSE); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + NullDataLength, _FALSE, _FALSE, _FALSE); + + CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //Qos null data * 1 page + RsvdPageLoc.LocQosNull = TotalPageNum; + DBG_871X("LocQosNull: %d\n", RsvdPageLoc.LocQosNull); + rtw_hal_construct_NullFunctionData( + adapter, + &ReservedPagePacket[BufIndex], + &QosNullLength, + get_my_bssid(&pmlmeinfo->network), + _TRUE, 0, 0, _FALSE); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + QosNullLength, _FALSE, _FALSE, _FALSE); + + CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + +#ifdef CONFIG_WOWLAN + if (pwrctl->wowlan_mode == _TRUE && + check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + //ARP RSP * 1 page + rtw_get_current_ip_address(adapter, currentip); + + RsvdPageLoc.LocArpRsp= TotalPageNum; + + rtw_hal_construct_ARPRsp( + adapter, + &ReservedPagePacket[BufIndex], + &ARPLegnth, + currentip); + + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + ARPLegnth, _FALSE, _FALSE, _TRUE); + + CurtPktPageNum = (u8)PageNum(TxDescLen + ARPLegnth, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //3 SEC IV * 1 page + rtw_get_sec_iv(adapter, cur_dot11txpn, + get_my_bssid(&pmlmeinfo->network)); + + RsvdPageLoc.LocRemoteCtrlInfo = TotalPageNum; + + _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, + cur_dot11txpn, _AES_IV_LEN_); + + CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, PageSize); + + TotalPageNum += CurtPktPageNum; +#ifdef CONFIG_GTK_OL + BufIndex += (CurtPktPageNum*PageSize); + + //if the ap staion info. exists, get the kek, kck from staion info. + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) { + _rtw_memset(kek, 0, RTW_KEK_LEN); + _rtw_memset(kck, 0, RTW_KCK_LEN); + DBG_8192C("%s, KEK, KCK download rsvd page all zero \n", + __func__); + } else { + _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN); + _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN); + } + + //3 KEK, KCK + RsvdPageLoc.LocGTKInfo = TotalPageNum; + _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, + kck, RTW_KCK_LEN); + _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+RTW_KCK_LEN, + kek, RTW_KEK_LEN); +#if 0 + { + int i; + printk("\ntoFW KCK: "); + for(i=0;i<16; i++) + printk(" %02x ", kck[i]); + printk("\ntoFW KEK: "); + for(i=0;i<16; i++) + printk(" %02x ", kek[i]); + printk("\n"); + } +#endif + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", + // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], + // (TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN)); + + CurtPktPageNum = (u8)PageNum(TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //3 GTK Response + RsvdPageLoc.LocGTKRsp= TotalPageNum; + rtw_hal_construct_GTKRsp( + adapter, + &ReservedPagePacket[BufIndex], + >KLegnth); + + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + GTKLegnth, _FALSE, _FALSE, _TRUE); +#if 0 + { + int gj; + printk("123GTK pkt=> \n"); + for(gj=0; gj < GTKLegnth+TxDescLen; gj++) { + printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]); + if ((gj + 1)%16==0) + printk("\n"); + } + printk(" <=end\n"); + } +#endif + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n", + // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], + // (TxDescLen + GTKLegnth)); + + CurtPktPageNum = (u8)PageNum(TxDescLen + GTKLegnth, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //below page is empty for GTK extension memory + //3(11) GTK EXT MEM + RsvdPageLoc.LocGTKEXTMEM= TotalPageNum; + + CurtPktPageNum = 2; + + TotalPageNum += CurtPktPageNum; + //extension memory for FW + TotalPacketLen = BufIndex-TxDescLen + (PageSize*CurtPktPageNum); +#else //CONFIG_GTK_OL + TotalPacketLen = BufIndex + _AES_IV_LEN_; +#endif //CONFIG_GTK_OL + } else if (pwrctl->wowlan_pno_enable == _TRUE) { +#ifdef CONFIG_PNO_SUPPORT + if (pwrctl->pno_in_resume == _FALSE && + pwrctl->pno_inited == _TRUE) { + + //Broadcast Probe Request + RsvdPageLoc.LocProbePacket = TotalPageNum; + + DBG_871X("loc_probe_req: %d\n", + RsvdPageLoc.LocProbePacket); + + rtw_hal_construct_ProbeReq( + adapter, + &ReservedPagePacket[BufIndex], + &ProbeReqLength, + NULL); + + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + ProbeReqLength, _FALSE, _FALSE, _FALSE); + +#ifdef CONFIG_PNO_SET_DEBUG + { + int gj; + printk("probe req pkt=> \n"); + for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) { + printk(" %02x ",ReservedPagePacket[BufIndex- TxDescLen + gj]); + if ((gj + 1)%8==0) + printk("\n"); + } + printk(" <=end\n"); + } +#endif + CurtPktPageNum = + (u8)PageNum(TxDescLen + ProbeReqLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //Hidden SSID Probe Request + ssid_num = pwrctl->pnlo_info->hidden_ssid_num; + + for (index = 0 ; index < ssid_num ; index++) { + pwrctl->pnlo_info->loc_probe_req[index] = + TotalPageNum; + + rtw_hal_construct_ProbeReq( + adapter, + &ReservedPagePacket[BufIndex], + &ProbeReqLength, + &pwrctl->pno_ssid_list->node[index]); + + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + ProbeReqLength, _FALSE, _FALSE, _FALSE); + +#ifdef CONFIG_PNO_SET_DEBUG + { + int gj; + printk("probe req pkt=> \n"); + for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) { + printk(" %02x ", ReservedPagePacket[BufIndex- TxDescLen + gj]); + if ((gj + 1)%8==0) + printk("\n"); + } + printk(" <=end\n"); + } +#endif + CurtPktPageNum = + (u8)PageNum(TxDescLen + ProbeReqLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + } + + //PNO INFO Page + RsvdPageLoc.LocPNOInfo = TotalPageNum; + rtw_hal_construct_PNO_info(adapter, + &ReservedPagePacket[BufIndex -TxDescLen], + &PNOLength); +#ifdef CONFIG_PNO_SET_DEBUG + { + int gj; + printk("PNO pkt=> \n"); + for(gj=0; gj < PNOLength; gj++) { + printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen +gj]); + if ((gj + 1)%8==0) + printk("\n"); + } + printk(" <=end\n"); + } +#endif + + CurtPktPageNum = (u8)PageNum_128(PNOLength); + TotalPageNum += CurtPktPageNum; + BufIndex += (CurtPktPageNum*PageSize); + + //SSID List Page + RsvdPageLoc.LocSSIDInfo = TotalPageNum; + rtw_hal_construct_ssid_list(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + &SSIDLegnth); +#ifdef CONFIG_PNO_SET_DEBUG + { + int gj; + printk("SSID list pkt=> \n"); + for(gj=0; gj < SSIDLegnth; gj++) { + printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]); + if ((gj + 1)%8==0) + printk("\n"); + } + printk(" <=end\n"); + } +#endif + CurtPktPageNum = (u8)PageNum_128(SSIDLegnth); + TotalPageNum += CurtPktPageNum; + BufIndex += (CurtPktPageNum*PageSize); + + //Scan Info Page + RsvdPageLoc.LocScanInfo = TotalPageNum; + rtw_hal_construct_scan_info(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + &ScanInfoLength); +#ifdef CONFIG_PNO_SET_DEBUG + { + int gj; + printk("Scan info pkt=> \n"); + for(gj=0; gj < ScanInfoLength; gj++) { + printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]); + if ((gj + 1)%8==0) + printk("\n"); + } + printk(" <=end\n"); + } +#endif + CurtPktPageNum = (u8)PageNum(ScanInfoLength, PageSize); + TotalPageNum += CurtPktPageNum; + BufIndex += (CurtPktPageNum*PageSize); + TotalPacketLen = BufIndex + ScanInfoLength; + } else { + TotalPacketLen = BufIndex + QosNullLength; + } +#endif //CONFIG_PNO_SUPPORT + } else { + TotalPacketLen = BufIndex + QosNullLength; + } +#else //CONFIG_WOWLAN + TotalPacketLen = BufIndex + QosNullLength; +#endif //CONFIG_WOWLAN + +#ifdef CONFIG_P2P_WOWLAN + if(_TRUE == pwrctl->wowlan_p2p_mode) + { + + // P2P Beacon + RsvdPageLoc.LocP2PBeacon= TotalPageNum; + rtw_hal_construct_P2PBeacon( + adapter, + &ReservedPagePacket[BufIndex], + &P2PBCNLength); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + P2PBCNLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", + // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (P2PBCNLength+TxDescLen)); + + CurtPktPageNum = (u8)PageNum(TxDescLen + P2PBCNLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + // P2P Probe rsp + RsvdPageLoc.LocP2PProbeRsp = TotalPageNum; + rtw_hal_construct_P2PProbeRsp( + adapter, + &ReservedPagePacket[BufIndex], + &P2PProbeRspLength); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + P2PProbeRspLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", + // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (P2PProbeRspLength+TxDescLen)); + + CurtPktPageNum = (u8)PageNum(TxDescLen + P2PProbeRspLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //P2P nego rsp + RsvdPageLoc.LocNegoRsp = TotalPageNum; + rtw_hal_construct_P2PNegoRsp( + adapter, + &ReservedPagePacket[BufIndex], + &P2PNegoRspLength); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + P2PNegoRspLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", + // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (NegoRspLength+TxDescLen)); + + CurtPktPageNum = (u8)PageNum(TxDescLen + P2PNegoRspLength, PageSize); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + //P2P invite rsp + RsvdPageLoc.LocInviteRsp = TotalPageNum; + rtw_hal_construct_P2PInviteRsp( + adapter, + &ReservedPagePacket[BufIndex], + &P2PInviteRspLength); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + P2PInviteRspLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", + // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (InviteRspLength+TxDescLen)); + + CurtPktPageNum = (u8)PageNum(TxDescLen + P2PInviteRspLength, PageSize); + + TotalPageNum += CurtPktPageNum; - if (adapter->iface_type == IFACE_PORT0) { - adapter->iface_type = IFACE_PORT1; - adapter->pbuddy_adapter->iface_type = IFACE_PORT0; - DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n", - ADPT_ARG(adapter->pbuddy_adapter), ADPT_ARG(adapter)); - } else { - adapter->iface_type = IFACE_PORT0; - adapter->pbuddy_adapter->iface_type = IFACE_PORT1; - DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n", - ADPT_ARG(adapter), ADPT_ARG(adapter->pbuddy_adapter)); - } + BufIndex += (CurtPktPageNum*PageSize); + + //P2P provision discovery rsp + RsvdPageLoc.LocPDRsp = TotalPageNum; + rtw_hal_construct_P2PProvisionDisRsp( + adapter, + &ReservedPagePacket[BufIndex], + &P2PPDRspLength); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + P2PPDRspLength, _FALSE, _FALSE, _FALSE); -#ifdef DBG_RUNTIME_PORT_SWITCH - msr = rtw_read8(adapter, MSR); - bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL); - bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1); + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", + // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (PDRspLength+TxDescLen)); - for (i=0; i<2; i++) - atimwnd[i] = rtw_read8(adapter, REG_ATIMWND+i); - for (i=0; i<2; i++) - atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1+i); + CurtPktPageNum = (u8)PageNum(TxDescLen + P2PPDRspLength, PageSize); - for (i=0; i<8; i++) - tsftr[i] = rtw_read8(adapter, REG_TSFTR+i); - for (i=0; i<8; i++) - tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1+i); + TotalPageNum += CurtPktPageNum; - for (i=0; i<6; i++) - macid[i] = rtw_read8(adapter, REG_MACID+i); + BufIndex += (CurtPktPageNum*PageSize); - for (i=0; i<6; i++) - bssid[i] = rtw_read8(adapter, REG_BSSID+i); + TotalPacketLen = BufIndex + P2PPDRspLength; + } +#endif //CONFIG_P2P_WOWLAN - for (i=0; i<6; i++) - macid_1[i] = rtw_read8(adapter, REG_MACID1+i); + if(TotalPacketLen > MaxRsvdPageBufSize) { + DBG_871X("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n", + __FUNCTION__, TotalPacketLen,MaxRsvdPageBufSize); + goto error; + } else { + // update attribute + pattrib = &pcmdframe->attrib; + update_mgntframe_attrib(adapter, pattrib); + pattrib->qsel = 0x10; + pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset; +#ifdef CONFIG_PCI_HCI + dump_mgntframe(adapter, pcmdframe); +#else + dump_mgntframe_and_wait(adapter, pcmdframe, 100); +#endif + } - for (i=0; i<6; i++) - bssid_1[i] = rtw_read8(adapter, REG_BSSID1+i); + DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", + __func__,TotalPacketLen,TotalPageNum); + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc); + if (pwrctl->wowlan_mode == _TRUE) + rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc); + } else if (pwrctl->wowlan_pno_enable) { +#ifdef CONFIG_PNO_SUPPORT + rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc); + if(pwrctl->pno_in_resume) + rtw_hal_set_scan_offload_info_cmd(adapter, + &RsvdPageLoc, 0); + else + rtw_hal_set_scan_offload_info_cmd(adapter, + &RsvdPageLoc, 1); +#endif //CONFIG_PNO_SUPPORT + } +#ifdef CONFIG_P2P_WOWLAN + if(_TRUE == pwrctl->wowlan_p2p_mode) + rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc); + +#endif //CONFIG_P2P_WOWLAN + return; +error: + rtw_free_xmitframe(pxmitpriv, pcmdframe); +} - DBG_871X(FUNC_ADPT_FMT" after switch\n" - "msr:0x%02x\n" - "bcn_ctrl:0x%02x\n" - "bcn_ctrl_1:0x%02x\n" - "atimwnd:%u\n" - "atimwnd_1:%u\n" - "tsftr:%llu\n" - "tsftr1:%llu\n" - "macid:"MAC_FMT"\n" - "bssid:"MAC_FMT"\n" - "macid_1:"MAC_FMT"\n" - "bssid_1:"MAC_FMT"\n" - , FUNC_ADPT_ARG(adapter) - , msr - , bcn_ctrl - , bcn_ctrl_1 - , *((u16*)atimwnd) - , *((u16*)atimwnd_1) - , *((u64*)tsftr) - , *((u64*)tsftr_1) - , MAC_ARG(macid) - , MAC_ARG(bssid) - , MAC_ARG(macid_1) - , MAC_ARG(bssid_1) - ); -#endif /* DBG_RUNTIME_PORT_SWITCH */ +static void rtw_hal_download_rsvd_page(_adapter* adapter, u8 mstatus) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + BOOLEAN bcn_valid = _FALSE; + u8 DLBcnCount=0; + u32 poll = 0; + u8 val8; -#endif /* CONFIG_RUNTIME_PORT_SWITCH */ -#endif /* CONFIG_CONCURRENT_MODE */ +_func_enter_; + + DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d mstatus(%x)\n", + FUNC_ADPT_ARG(adapter), get_iface_type(adapter), mstatus); + + if(mstatus == RT_MEDIA_CONNECT) { + BOOLEAN bRecover = _FALSE; + u8 v8; + + // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. + // Suggested by filen. Added by tynli. + rtw_write16(adapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid)); + + // set REG_CR bit 8 + v8 = rtw_read8(adapter, REG_CR+1); + v8 |= BIT(0); // ENSWBCN + rtw_write8(adapter, REG_CR+1, v8); + + // Disable Hw protection for a time which revserd for Hw sending beacon. + // Fix download reserved page packet fail that access collision with the protection time. + // 2010.05.11. Added by tynli. + val8 = rtw_read8(adapter, REG_BCN_CTRL); + val8 &= ~EN_BCN_FUNCTION; + val8 |= DIS_TSF_UDT; + rtw_write8(adapter, REG_BCN_CTRL, val8); + + // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. + if (pHalData->RegFwHwTxQCtrl & BIT(6)) + bRecover = _TRUE; + + // To tell Hw the packet is not a real beacon frame. + rtw_write8(adapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6)); + pHalData->RegFwHwTxQCtrl &= ~BIT(6); + + // Clear beacon valid check bit. + rtw_hal_set_hwreg(adapter, HW_VAR_BCN_VALID, NULL); + rtw_hal_set_hwreg(adapter, HW_VAR_DL_BCN_SEL, NULL); + + DLBcnCount = 0; + poll = 0; + do { + // download rsvd page. + rtw_hal_set_fw_rsvd_page(adapter, 0); + + DLBcnCount++; + do { + rtw_yield_os(); + //rtw_mdelay_os(10); + // check rsvd page download OK. + rtw_hal_get_hwreg(adapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid)); + poll++; + } while(!bcn_valid && (poll%10)!=0 && !adapter->bSurpriseRemoved && !adapter->bDriverStopped); + }while(!bcn_valid && DLBcnCount<=100 && !adapter->bSurpriseRemoved && !adapter->bDriverStopped); + + if(adapter->bSurpriseRemoved || adapter->bDriverStopped) { + DBG_871X(ADPT_FMT": 0 bSurpriseRemoved:%d, bDriverStopped:%d\n", + ADPT_ARG(adapter) ,adapter->bSurpriseRemoved, + adapter->bDriverStopped); + } else if(!bcn_valid) { + DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n", + ADPT_ARG(adapter) ,DLBcnCount, poll); + } else { + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + pwrctl->fw_psmode_iface_id = adapter->iface_id; + DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n", + ADPT_ARG(adapter), DLBcnCount, poll); + } + + // 2010.05.11. Added by tynli. + val8 = rtw_read8(adapter, REG_BCN_CTRL); + val8 |= EN_BCN_FUNCTION; + val8 &= ~DIS_TSF_UDT; + rtw_write8(adapter, REG_BCN_CTRL, val8); + + // To make sure that if there exists an adapter which would like to send beacon. + // If exists, the origianl value of 0x422[6] will be 1, we should check this to + // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause + // the beacon cannot be sent by HW. + // 2010.06.23. Added by tynli. + if(bRecover) { + rtw_write8(adapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6)); + pHalData->RegFwHwTxQCtrl |= BIT(6); + } + + // Clear CR[8] or beacon packet will not be send to TxBuf anymore. + v8 = rtw_read8(adapter, REG_CR+1); + v8 &= ~BIT(0); // ~ENSWBCN + rtw_write8(adapter, REG_CR+1, v8); + } + +_func_exit_; } +#endif //CONFIG_WOWLAN void SetHwReg(_adapter *adapter, u8 variable, u8 *val) { @@ -1047,94 +5031,288 @@ void SetHwReg(_adapter *adapter, u8 variable, u8 *val) _func_enter_; switch (variable) { - case HW_VAR_PORT_SWITCH: - hw_var_port_switch(adapter); - break; - case HW_VAR_INIT_RTS_RATE: - { - u16 brate_cfg = *((u16*)val); - u8 rate_index = 0; - HAL_VERSION *hal_ver = &hal_data->VersionID; + case HW_VAR_INITIAL_GAIN: + { + u32 rx_gain = ((u32 *)(val))[0]; + + if(rx_gain == 0xff){//restore rx gain + //ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue); + odm_PauseDIG(odm, ODM_RESUME_DIG,rx_gain); + } + else{ + //pDigTable->BackupIGValue = pDigTable->CurIGValue; + //ODM_Write_DIG(podmpriv,rx_gain); + odm_PauseDIG(odm, ODM_PAUSE_DIG,rx_gain); + } + } + break; + case HW_VAR_PORT_SWITCH: + hw_var_port_switch(adapter); + break; + case HW_VAR_INIT_RTS_RATE: + { + u16 brate_cfg = *((u16*)val); + u8 rate_index = 0; + HAL_VERSION *hal_ver = &hal_data->VersionID; - if (IS_81XXC(*hal_ver) ||IS_92D(*hal_ver) || IS_8723_SERIES(*hal_ver) || IS_8188E(*hal_ver)) { + if (IS_81XXC(*hal_ver) ||IS_92D(*hal_ver) || IS_8723_SERIES(*hal_ver) || IS_8188E(*hal_ver)) { - while (brate_cfg > 0x1) { - brate_cfg = (brate_cfg >> 1); - rate_index++; + while (brate_cfg > 0x1) { + brate_cfg = (brate_cfg >> 1); + rate_index++; + } + rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index); + } else { + rtw_warn_on(1); } - rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index); - } else { - rtw_warn_on(1); } - } - break; - case HW_VAR_SEC_CFG: - { - #if defined(CONFIG_CONCURRENT_MODE) && !defined(DYNAMIC_CAMID_ALLOC) - // enable tx enc and rx dec engine, and no key search for MC/BC - rtw_write8(adapter, REG_SECCFG, SCR_NoSKMC|SCR_RxDecEnable|SCR_TxEncEnable); - #elif defined(DYNAMIC_CAMID_ALLOC) - u16 reg_scr; - - reg_scr = rtw_read16(adapter, REG_SECCFG); - rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable); - #else - rtw_write8(adapter, REG_SECCFG, *((u8*)val)); - #endif - } - break; - case HW_VAR_SEC_DK_CFG: - { - struct security_priv *sec = &adapter->securitypriv; - u8 reg_scr = rtw_read8(adapter, REG_SECCFG); - - if (val) /* Enable default key related setting */ + break; + case HW_VAR_SEC_CFG: { - reg_scr |= SCR_TXBCUSEDK; - if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) - reg_scr |= (SCR_RxUseDK|SCR_TxUseDK); + #if defined(CONFIG_CONCURRENT_MODE) && !defined(DYNAMIC_CAMID_ALLOC) + // enable tx enc and rx dec engine, and no key search for MC/BC + rtw_write8(adapter, REG_SECCFG, SCR_NoSKMC|SCR_RxDecEnable|SCR_TxEncEnable); + #elif defined(DYNAMIC_CAMID_ALLOC) + u16 reg_scr; + + reg_scr = rtw_read16(adapter, REG_SECCFG); + rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable); + #else + rtw_write8(adapter, REG_SECCFG, *((u8*)val)); + #endif } - else /* Disable default key related setting */ + break; + case HW_VAR_SEC_DK_CFG: { - reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK); - } + struct security_priv *sec = &adapter->securitypriv; + u8 reg_scr = rtw_read8(adapter, REG_SECCFG); - rtw_write8(adapter, REG_SECCFG, reg_scr); - } - break; - case HW_VAR_DM_FLAG: - odm->SupportAbility = *((u32*)val); - break; - case HW_VAR_DM_FUNC_OP: - if (*((u8*)val) == _TRUE) { - /* save dm flag */ - odm->BK_SupportAbility = odm->SupportAbility; - } else { - /* restore dm flag */ - odm->SupportAbility = odm->BK_SupportAbility; + if (val) /* Enable default key related setting */ + { + reg_scr |= SCR_TXBCUSEDK; + if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) + reg_scr |= (SCR_RxUseDK|SCR_TxUseDK); + } + else /* Disable default key related setting */ + { + reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK); + } + + rtw_write8(adapter, REG_SECCFG, reg_scr); } - break; - case HW_VAR_DM_FUNC_SET: - if(*((u32*)val) == DYNAMIC_ALL_FUNC_ENABLE){ - struct dm_priv *dm = &hal_data->dmpriv; - dm->DMFlag = dm->InitDMFlag; - odm->SupportAbility = dm->InitODMFlag; - } else { - odm->SupportAbility |= *((u32 *)val); + break; + case HW_VAR_DM_FLAG: + odm->SupportAbility = *((u32*)val); + break; + case HW_VAR_DM_FUNC_OP: + if (*((u8*)val) == _TRUE) { + /* save dm flag */ + odm->BK_SupportAbility = odm->SupportAbility; + } else { + /* restore dm flag */ + odm->SupportAbility = odm->BK_SupportAbility; + } + break; + case HW_VAR_DM_FUNC_SET: + if(*((u32*)val) == DYNAMIC_ALL_FUNC_ENABLE){ + struct dm_priv *dm = &hal_data->dmpriv; + dm->DMFlag = dm->InitDMFlag; + odm->SupportAbility = dm->InitODMFlag; + } else { + odm->SupportAbility |= *((u32 *)val); + } + break; + case HW_VAR_DM_FUNC_CLR: + /* + * input is already a mask to clear function + * don't invert it again! George,Lucas@20130513 + */ + odm->SupportAbility &= *((u32 *)val); + break; + case HW_VAR_ASIX_IOT: + // enable ASIX IOT function + if (*((u8*)val) == _TRUE) { + // 0xa2e[0]=0 (disable rake receiver) + rtw_write8(adapter, rCCK0_FalseAlarmReport+2, + rtw_read8(adapter, rCCK0_FalseAlarmReport+2) & ~(BIT0)); + // 0xa1c=0xa0 (reset channel estimation if signal quality is bad) + rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0); + } else { + // restore reg:0xa2e, reg:0xa1c + rtw_write8(adapter, rCCK0_FalseAlarmReport+2, + rtw_read8(adapter, rCCK0_FalseAlarmReport+2)|(BIT0)); + rtw_write8(adapter, rCCK0_DSPParameter2, 0x00); + } + break; +#ifdef CONFIG_WOWLAN + case HW_VAR_WOWLAN: + { + struct wowlan_ioctl_param *poidparam; + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + struct security_priv *psecuritypriv = &adapter->securitypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct hal_ops *pHalFunc = &adapter->HalFunc; + struct sta_info *psta = NULL; + int res; + u16 media_status_rpt; + u8 val8; + + poidparam = (struct wowlan_ioctl_param *)val; + switch (poidparam->subcode) { + case WOWLAN_ENABLE: + DBG_871X_LEVEL(_drv_always_, "WOWLAN_ENABLE\n"); + +#ifdef CONFIG_GTK_OL + if (psecuritypriv->dot11PrivacyAlgrthm == _AES_) + rtw_hal_fw_sync_cam_id(adapter); +#endif + if (IS_HARDWARE_TYPE_8723B(adapter)) + rtw_hal_backup_rate(adapter); + + if (pHalFunc->hal_set_wowlan_fw != NULL) + pHalFunc->hal_set_wowlan_fw(adapter, _TRUE); + else + DBG_871X("hal_set_wowlan_fw is null\n"); + + rtw_hal_download_rsvd_page(adapter, RT_MEDIA_CONNECT); + + if (!pwrctl->wowlan_pno_enable) { + psta = rtw_get_stainfo(&adapter->stapriv, + get_bssid(pmlmepriv)); + media_status_rpt = + (u16)((psta->mac_id<<8)|RT_MEDIA_CONNECT); + if (psta != NULL) { + rtw_hal_set_hwreg(adapter, + HW_VAR_H2C_MEDIA_STATUS_RPT, + (u8 *)&media_status_rpt); + } + } + + rtw_msleep_os(2); + + if (IS_HARDWARE_TYPE_8188E(adapter)) + rtw_hal_disable_tx_report(adapter); + + //RX DMA stop + res = rtw_hal_pause_rx_dma(adapter); + if (res == _FAIL) + DBG_871X_LEVEL(_drv_always_, "[WARNING] pause RX DMA fail\n"); + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + //Enable CPWM2 only. + res = rtw_hal_enable_cpwm2(adapter); + if (res == _FAIL) + DBG_871X_LEVEL(_drv_always_, "[WARNING] enable cpwm2 fail\n"); +#endif + + //Set WOWLAN H2C command. + DBG_871X_LEVEL(_drv_always_, "Set WOWLan cmd\n"); + rtw_hal_set_fw_wow_related_cmd(adapter, 1); + + res = rtw_hal_check_wow_ctrl(adapter, _TRUE); + if (res == _FALSE) + DBG_871X("[Error]%s: set wowlan CMD fail!!\n", __func__); + + pwrctl->wowlan_wake_reason = + rtw_read8(adapter, REG_WOWLAN_WAKE_REASON); + + DBG_871X_LEVEL(_drv_always_, + "wowlan_wake_reason: 0x%02x\n", + pwrctl->wowlan_wake_reason); +#ifdef CONFIG_GTK_OL_DBG + dump_cam_table(adapter); +#endif +#ifdef CONFIG_USB_HCI + if (adapter->intf_stop) + adapter->intf_stop(adapter); + + /* Invoid SE0 reset signal during suspending*/ + rtw_write8(adapter, REG_RSV_CTRL, 0x20); + rtw_write8(adapter, REG_RSV_CTRL, 0x60); +#endif //CONFIG_USB_HCI + break; + case WOWLAN_DISABLE: + DBG_871X_LEVEL(_drv_always_, "WOWLAN_DISABLE\n"); + + if (!pwrctl->wowlan_pno_enable) { + psta = rtw_get_stainfo(&adapter->stapriv, + get_bssid(pmlmepriv)); + + if (psta != NULL) { + media_status_rpt = + (u16)((psta->mac_id<<8)|RT_MEDIA_DISCONNECT); + rtw_hal_set_hwreg(adapter, + HW_VAR_H2C_MEDIA_STATUS_RPT, + (u8 *)&media_status_rpt); + } else { + DBG_871X("%s: psta is null\n", __func__); + } + } + + if (0) { + DBG_871X("0x630:0x%02x\n", + rtw_read8(adapter, 0x630)); + DBG_871X("0x631:0x%02x\n", + rtw_read8(adapter, 0x631)); + } + + pwrctl->wowlan_wake_reason = rtw_read8(adapter, + REG_WOWLAN_WAKE_REASON); + + DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n", + pwrctl->wowlan_wake_reason); + + rtw_hal_set_fw_wow_related_cmd(adapter, 0); + + res = rtw_hal_check_wow_ctrl(adapter, _FALSE); + if (res == _FALSE) { + DBG_871X("[Error]%s: disable WOW cmd fail\n!!", __func__); + rtw_hal_force_enable_rxdma(adapter); + } + + if (IS_HARDWARE_TYPE_8188E(adapter)) + rtw_hal_enable_tx_report(adapter); + + rtw_hal_update_tx_iv(adapter); + +#ifdef CONFIG_GTK_OL + if (psecuritypriv->dot11PrivacyAlgrthm == _AES_) + rtw_hal_update_gtk_offload_info(adapter); +#endif //CONFIG_GTK_OL + + if (pHalFunc->hal_set_wowlan_fw != NULL) + pHalFunc->hal_set_wowlan_fw(adapter, _FALSE); + else + DBG_871X("hal_set_wowlan_fw is null\n"); +#ifdef CONFIG_GPIO_WAKEUP + rtw_clear_hostwakeupgpio(adapter); +#endif + if((pwrctl->wowlan_wake_reason != FWDecisionDisconnect) && + (pwrctl->wowlan_wake_reason != Rx_Pairwisekey) && + (pwrctl->wowlan_wake_reason != Rx_DisAssoc) && + (pwrctl->wowlan_wake_reason != Rx_DeAuth)) { + + rtw_hal_download_rsvd_page(adapter, RT_MEDIA_CONNECT); + if (psta != NULL) { + media_status_rpt = + (u16)((psta->mac_id<<8)|RT_MEDIA_CONNECT); + rtw_hal_set_hwreg(adapter, + HW_VAR_H2C_MEDIA_STATUS_RPT, + (u8 *)&media_status_rpt); + } + } + break; + default: + break; + } } break; - case HW_VAR_DM_FUNC_CLR: - /* - * input is already a mask to clear function - * don't invert it again! George,Lucas@20130513 - */ - odm->SupportAbility &= *((u32 *)val); - break; - default: - if (0) - DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n", - FUNC_ADPT_ARG(adapter), variable); - break; +#endif //CONFIG_WOWLAN + default: + if (0) + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n", + FUNC_ADPT_ARG(adapter), variable); + break; } _func_exit_; @@ -1187,7 +5365,7 @@ SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) break; case HAL_DEF_DBG_RX_INFO_DUMP: { - PFALSE_ALARM_STATISTICS FalseAlmCnt = &(odm->FalseAlmCnt); + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( odm , PHYDM_FALSEALMCNT); pDIG_T pDM_DigTable = &odm->DM_DigTable; DBG_871X("============ Rx Info dump ===================\n"); @@ -1218,11 +5396,15 @@ SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) struct dm_priv *dm = &hal_data->dmpriv; if(dm_func == 0){ //disable all dynamic func + pDIG_T pDM_DigTable = &odm->DM_DigTable; odm->SupportAbility = DYNAMIC_FUNC_DISABLE; + pDM_DigTable->bStopDIG = _TRUE; DBG_8192C("==> Disable all dynamic function...\n"); } else if(dm_func == 1){//disable DIG + pDIG_T pDM_DigTable = &odm->DM_DigTable; odm->SupportAbility &= (~DYNAMIC_BB_DIG); + pDM_DigTable->bStopDIG = _TRUE; DBG_8192C("==> Disable DIG...\n"); } else if(dm_func == 2){//disable High power @@ -1242,9 +5424,11 @@ SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) if(!(odm->SupportAbility & DYNAMIC_BB_DIG)) { DIG_T *pDigTable = &odm->DM_DigTable; pDigTable->CurIGValue= rtw_read8(adapter, 0xc50); + pDigTable->bStopDIG = _FALSE; } dm->DMFlag |= DYNAMIC_FUNC_BT; odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE; + DBG_8192C("==> Turn on all dynamic function...\n"); } } @@ -1258,6 +5442,9 @@ SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) case HAL_DEF_ANT_DETECT: hal_data->AntDetection = *((u8 *)value); break; + case HAL_DEF_DBG_DIS_PWT: + hal_data->bDisableTXPowerTraining = *((u8*)value); + break; default: DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable); bResult = _FAIL; @@ -1314,6 +5501,9 @@ GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) case HAL_DEF_TX_PAGE_SIZE: *(( u32*)value) = PAGE_SIZE_128; break; + case HAL_DEF_DBG_DIS_PWT: + *(u8*)value = hal_data->bDisableTXPowerTraining; + break; default: DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable); bResult = _FAIL; @@ -1382,6 +5572,10 @@ void SetHalODMVar( case HAL_ODM_WIFI_DISPLAY_STATE: ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DISPLAY,bSet); break; + case HAL_ODM_REGULATION: + ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G); + ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G); + break; #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) case HAL_ODM_NOISE_MONITOR: { @@ -1682,18 +5876,17 @@ void rtw_hal_check_rxfifo_full(_adapter *adapter) //switch counter to RX fifo if(IS_81XXC(pHalData->VersionID) || IS_92D(pHalData->VersionID) || IS_8188E(pHalData->VersionID) || IS_8723_SERIES(pHalData->VersionID) - || IS_8812_SERIES(pHalData->VersionID) || IS_8821_SERIES(pHalData->VersionID)) + || IS_8812_SERIES(pHalData->VersionID) || IS_8821_SERIES(pHalData->VersionID) + || IS_8723B_SERIES(pHalData->VersionID) || IS_8192E(pHalData->VersionID)) { rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); save_cnt = _TRUE; } - else if(IS_8723B_SERIES(pHalData->VersionID) || IS_8192E(pHalData->VersionID)) + else { - //printk("8723b or 8192e , MAC_667 set 0xf0\n"); - rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0); - save_cnt = _TRUE; + //todo: other chips } - //todo: other chips + if(save_cnt) { @@ -1730,7 +5923,7 @@ void linked_info_dump(_adapter *padapter,u8 benable) #endif // CONFIG_IPS #ifdef CONFIG_LPS - rtw_pm_set_lps(padapter, pwrctrlpriv->ips_org_mode); + rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt ); #endif // CONFIG_LPS } padapter->bLinkInfoDump = benable ; @@ -2135,19 +6328,23 @@ void rtw_bb_rf_gain_offset(_adapter *padapter) if (value & BIT4) { DBG_871X("Offset RF Gain.\n"); DBG_871X("Offset RF Gain. padapter->eeprompriv.EEPROMRFGainVal=0x%x\n",padapter->eeprompriv.EEPROMRFGainVal); - + if(padapter->eeprompriv.EEPROMRFGainVal != 0xff){ - if (pHalData->ant_path == ODM_RF_PATH_A) + + if(pHalData->ant_path == ODM_RF_PATH_A) { GainValue=(padapter->eeprompriv.EEPROMRFGainVal & 0x0f); - else + + } else { GainValue=(padapter->eeprompriv.EEPROMRFGainVal & 0xf0)>>4; + } DBG_871X("Ant PATH_%d GainValue Offset = 0x%x\n",(pHalData->ant_path == ODM_RF_PATH_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B),GainValue); - + for (i = 0; i < ArrayLen; i += 2 ) { + //DBG_871X("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x \n",i,Array[i],Array[i]+1); v1 = Array[i]; v2 = Array[i+1]; - if ( v1 == GainValue ) { + if ( v1 == GainValue ) { DBG_871X("Offset RF Gain. got v1 =0x%x ,v2 =0x%x \n",v1,v2); target=v2; break; @@ -2162,7 +6359,7 @@ void rtw_bb_rf_gain_offset(_adapter *padapter) DBG_871X("Offset RF Gain. After reg 0x7f=0x%08x\n",res); - } else { + }else { DBG_871X("Offset RF Gain. padapter->eeprompriv.EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n",padapter->eeprompriv.EEPROMRFGainVal); } @@ -2224,7 +6421,7 @@ void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer) if((pHalData->UsbRxAggMode == USB_RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) { if(pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30) - rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,0x1010); + rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,0x1003); else rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,0x2005); //dmc agg th 20K @@ -2234,3 +6431,167 @@ void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer) #endif } +//bus-agg check for SoftAP mode +inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter,u8 pre_qsel,u8 next_qsel) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 chk_rst = _SUCCESS; + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return chk_rst; + + //if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) + // return chk_rst; + + if( ((pre_qsel == QSLT_HIGH)||((next_qsel== QSLT_HIGH))) + && (pre_qsel != next_qsel )){ + //DBG_871X("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", + // pre_qsel,next_qsel); + chk_rst = _FAIL; + } + return chk_rst; +} + +/* + * Description: + * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload + * contant. + * + * Input: + * adapter: adapter pointer. + * page_num: The max. page number that user want to dump. + * page_size: page size of each page. eg. 128 bytes, 256 bytes. + */ +void dump_TX_FIFO(_adapter* padapter, u8 page_num, u16 page_size){ + + int i; + u8 val = 0; + u8 base = 0; + u32 addr = 0; + u32 count = (page_size / 8); + + if (page_num <= 0) { + DBG_871X("!!%s: incorrect input page_num paramter!\n", __func__); + return; + } + + if (page_size < 128 || page_size > 256) { + DBG_871X("!!%s: incorrect input page_size paramter!\n", __func__); + return; + } + + DBG_871X("+%s+\n", __func__); + val = rtw_read8(padapter, 0x106); + rtw_write8(padapter, 0x106, 0x69); + DBG_871X("0x106: 0x%02x\n", val); + base = rtw_read8(padapter, 0x209); + DBG_871X("0x209: 0x%02x\n", base); + + addr = ((base) * page_size)/8; + for (i = 0 ; i < page_num * count ; i+=2) { + rtw_write32(padapter, 0x140, addr + i); + printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); + rtw_write32(padapter, 0x140, addr + i + 1); + printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); + } +} + +#ifdef CONFIG_GPIO_API +u8 rtw_hal_get_gpio(_adapter* adapter, u8 gpio_num) +{ + u8 value; + u8 direction; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + + rtw_ps_deny(adapter, PS_DENY_IOCTL); + + DBG_871X("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate); + LeaveAllPowerSaveModeDirect(adapter); + + /* Read GPIO Direction */ + direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num; + + /* According the direction to read register value */ + if( direction ) + value = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1)& BIT(gpio_num)) >> gpio_num; + else + value = (rtw_read8(adapter, REG_GPIO_PIN_CTRL)& BIT(gpio_num)) >> gpio_num; + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); + DBG_871X("%s direction=%d value=%d\n",__FUNCTION__,direction,value); + + return value; +} + +int rtw_hal_set_gpio_output_value(_adapter* adapter, u8 gpio_num, BOOLEAN isHigh) +{ + u8 direction = 0; + u8 res = -1; + if (IS_HARDWARE_TYPE_8188E(adapter)){ + /* Check GPIO is 4~7 */ + if( gpio_num > 7 || gpio_num < 4) + { + DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__); + return -1; + } + } + + rtw_ps_deny(adapter, PS_DENY_IOCTL); + + LeaveAllPowerSaveModeDirect(adapter); + + /* Read GPIO direction */ + direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num; + + /* If GPIO is output direction, setting value. */ + if( direction ) + { + if(isHigh) + rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) | BIT(gpio_num)); + else + rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(gpio_num)); + + DBG_871X("%s Set gpio %x[%d]=%d\n",__FUNCTION__,REG_GPIO_PIN_CTRL+1,gpio_num,isHigh ); + res = 0; + } + else + { + DBG_871X("%s The gpio is input,not be set!\n",__FUNCTION__); + res = -1; + } + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); + return res; +} + +int rtw_hal_config_gpio(_adapter* adapter, u8 gpio_num, BOOLEAN isOutput) +{ + if (IS_HARDWARE_TYPE_8188E(adapter)){ + if( gpio_num > 7 || gpio_num < 4) + { + DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__); + return -1; + } + } + + DBG_871X("%s gpio_num =%d direction=%d\n",__FUNCTION__,gpio_num,isOutput); + + rtw_ps_deny(adapter, PS_DENY_IOCTL); + + LeaveAllPowerSaveModeDirect(adapter); + + if( isOutput ) + { + rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) | BIT(gpio_num)); + } + else + { + rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(gpio_num)); + } + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); + + return 0; +} + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com_phycfg.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com_phycfg.c index e2ddca765370..4866324cc7ec 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com_phycfg.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_com_phycfg.c @@ -2573,17 +2573,12 @@ Hal_ChannelPlanToRegulation( break; } - ODM_CmnInfoInit(odm, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G); - ODM_CmnInfoInit(odm, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G); + DBG_871X("%s ChannelPlan:0x%02x,Regulation(2_4G/5G):0x%02x,0x%02x\n", + __FUNCTION__,ChannelPlan,pHalData->Regulation2_4G,pHalData->Regulation5G); + } #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE - -extern char *rtw_phy_file_path; -char file_path[PATH_LENGTH_MAX]; - -#define GetLineFromBuffer(buffer) strsep(&buffer, "\n") - int phy_ConfigMACWithParaFile( IN PADAPTER Adapter, diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_dm.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_dm.c new file mode 100755 index 000000000000..46dab54b0839 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_dm.c @@ -0,0 +1,196 @@ +/****************************************************************************** + * + * Copyright(c) 2014 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#include +#include + +// A mapping from HalData to ODM. +ODM_BOARD_TYPE_E boardType(u8 InterfaceSel) +{ + ODM_BOARD_TYPE_E board = ODM_BOARD_DEFAULT; + +#ifdef CONFIG_PCI_HCI + INTERFACE_SELECT_PCIE pcie = (INTERFACE_SELECT_PCIE)InterfaceSel; + switch (pcie) + { + case INTF_SEL0_SOLO_MINICARD: + board |= ODM_BOARD_MINICARD; + break; + case INTF_SEL1_BT_COMBO_MINICARD: + board |= ODM_BOARD_BT; + board |= ODM_BOARD_MINICARD; + break; + default: + board = ODM_BOARD_DEFAULT; + break; + } + +#elif defined(CONFIG_USB_HCI) + INTERFACE_SELECT_USB usb = (INTERFACE_SELECT_USB)InterfaceSel; + switch (usb) + { + case INTF_SEL1_USB_High_Power: + board |= ODM_BOARD_EXT_LNA; + board |= ODM_BOARD_EXT_PA; + break; + case INTF_SEL2_MINICARD: + board |= ODM_BOARD_MINICARD; + break; + case INTF_SEL4_USB_Combo: + board |= ODM_BOARD_BT; + break; + case INTF_SEL5_USB_Combo_MF: + board |= ODM_BOARD_BT; + break; + case INTF_SEL0_USB: + case INTF_SEL3_USB_Solo: + default: + board = ODM_BOARD_DEFAULT; + break; + } + +#endif + //DBG_871X("===> boardType(): (pHalData->InterfaceSel, pDM_Odm->BoardType) = (%d, %d)\n", InterfaceSel, board); + + return board; +} + +void Init_ODM_ComInfo(_adapter *adapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + int i; + + _rtw_memset(pDM_Odm,0,sizeof(*pDM_Odm)); + + pDM_Odm->Adapter = adapter; + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PLATFORM, ODM_CE); + + if (adapter->interface_type == RTW_GSPI) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_INTERFACE, ODM_ITRF_SDIO); + else + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_INTERFACE, adapter->interface_type); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->VersionID)); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PATCH_ID, pEEPROM->CustomerID); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, adapter->registrypriv.wifi_spec); + + if (pHalData->rf_type == RF_1T1R) { + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); + } + else if (pHalData->rf_type == RF_2T2R){ + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); + } + else if (pHalData->rf_type == RF_1T2R){ + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); + } + +{ + //1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= + u8 odm_board_type = ODM_BOARD_DEFAULT; + + if (!IS_HARDWARE_TYPE_OLDER_THAN_8723A(adapter)) + { + if (pHalData->ExternalLNA_2G != 0) { + odm_board_type |= ODM_BOARD_EXT_LNA; + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_LNA, 1); + } + if (pHalData->ExternalLNA_5G != 0) { + odm_board_type |= ODM_BOARD_EXT_LNA_5G; + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_5G_EXT_LNA, 1); + } + if (pHalData->ExternalPA_2G != 0) { + odm_board_type |= ODM_BOARD_EXT_PA; + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_PA, 1); + } + if (pHalData->ExternalPA_5G != 0) { + odm_board_type |= ODM_BOARD_EXT_PA_5G; + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_5G_EXT_PA, 1); + } + if (pHalData->EEPROMBluetoothCoexist) + odm_board_type |= ODM_BOARD_BT; + + } else { + #ifdef CONFIG_USB_HCI + if (pHalData->InterfaceSel == INTF_SEL1_USB_High_Power + || pHalData->BoardType == BOARD_USB_High_PA /* This is legacy code for hal_data.BoardType */ + ) { + ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_EXT_LNA, 1); + ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_EXT_PA, 1); + } else + #endif + { + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_PA, pHalData->ExternalPA_2G); + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_LNA, pHalData->ExternalLNA_2G); + } + + odm_board_type = boardType(pHalData->InterfaceSel); + } + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_BOARD_TYPE, odm_board_type); + //1 ============== End of BoardType ============== +} + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G); + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_GPA, pHalData->TypeGPA); + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_APA, pHalData->TypeAPA); + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_GLNA, pHalData->TypeGLNA); + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_ALNA, pHalData->TypeALNA); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RFE_TYPE, pHalData->RFEType); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_TRSW, 0); + + /* Pointer reference */ + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_TX_UNI, &(dvobj->traffic_stat.tx_bytes)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_RX_UNI, &(dvobj->traffic_stat.rx_bytes)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_WM_MODE, &(pmlmeext->cur_wireless_mode)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BAND, &(pHalData->CurrentBandType)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_FORCED_RATE, &(pHalData->ForcedDataRate)); + + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_CHNL_OFFSET, &(pHalData->nCur40MhzPrimeSC)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_MODE, &(adapter->securitypriv.dot11PrivacyAlgrthm)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BW, &(pHalData->CurrentChannelBW)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_CHNL, &( pHalData->CurrentChannel)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_NET_CLOSED, &(adapter->net_closed)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_FORCED_IGI_LB, &(pHalData->u1ForcedIgiLb)); + + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SCAN, &(pmlmepriv->bScanInProcess)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_POWER_SAVING, &(pwrctl->bpower_saving)); + + for(i=0; i +#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ +int usb_write_async(struct usb_device *udev, u32 addr, void *pdata, u16 len) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + int ret; + + requesttype = VENDOR_WRITE;//write_out + request = REALTEK_USB_VENQT_CMD_REQ; + index = REALTEK_USB_VENQT_CMD_IDX;//n/a + + wvalue = (u16)(addr&0x0000ffff); + + ret = _usbctrl_vendorreq_async_write(udev, request, wvalue, index, pdata, len, requesttype); + + return ret; +} + +int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) +{ + u8 data; + int ret; + struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev; + struct usb_device *udev=pdvobjpriv->pusbdev; + + _func_enter_; + data = val; + ret = usb_write_async(udev, addr, &data, 1); + _func_exit_; + + return ret; +} + +int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) +{ + u16 data; + int ret; + struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev; + struct usb_device *udev=pdvobjpriv->pusbdev; + + _func_enter_; + data = val; + ret = usb_write_async(udev, addr, &data, 2); + _func_exit_; + + return ret; +} + +int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) +{ + u32 data; + int ret; + struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev; + struct usb_device *udev=pdvobjpriv->pusbdev; + + _func_enter_; + data = val; + ret = usb_write_async(udev, addr, &data, 4); + _func_exit_; + + return ret; +} +#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */ + + + +#ifdef CONFIG_RTL8192D +/* This function only works in 92DU chip. */ +void usb_read_reg_rf_byfw(struct intf_hdl *pintfhdl, + u16 byteCount, + u32 registerIndex, + PVOID buffer) +{ + u16 wPage = 0x0000, offset; + u32 BufferLengthRead; + PADAPTER Adapter = pintfhdl->padapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 RFPath=0,nPHY=0; + + RFPath =(u8) ((registerIndex&0xff0000)>>16); + + if (pHalData->interfaceIndex!=0) + { + nPHY = 1; //MAC1 + if(registerIndex&MAC1_ACCESS_PHY0)// MAC1 need to access PHY0 + nPHY = 0; + } + else + { + if(registerIndex&MAC0_ACCESS_PHY1) + nPHY = 1; + } + registerIndex &= 0xFF; + wPage = ((nPHY<<7)|(RFPath<<5)|8)<<8; + offset = (u16)registerIndex; + + // + // IN a vendor request to read back MAC register. + // + usbctrl_vendorreq(pintfhdl, 0x05, offset, wPage, buffer, byteCount, 0x01); + +} +#endif + +/* + 92DU chip needs to remask "value" parameter, this function only works in 92DU chip. +*/ +static inline void usb_value_remask(struct intf_hdl *pintfhdl, u16 *value) +{ +#ifdef CONFIG_RTL8192D + _adapter *padapter = pintfhdl->padapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if ((IS_HARDWARE_TYPE_8192DU(padapter)) && (pHalData->interfaceIndex!=0)) + { + if(*value<0x1000) + *value|=0x4000; + else if ((*value&MAC1_ACCESS_PHY0) && !(*value&0x8000)) // MAC1 need to access PHY0 + *value &= 0xFFF; + } +#endif +} + +u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + u16 len; + u8 data=0; + + _func_enter_; + + request = 0x05; + requesttype = 0x01;//read_in + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = 1; + usb_value_remask(pintfhdl, &wvalue); + usbctrl_vendorreq(pintfhdl, request, wvalue, index, + &data, len, requesttype); + + _func_exit_; + + return data; +} + +u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + u16 len; + u16 data=0; + + _func_enter_; + + request = 0x05; + requesttype = 0x01;//read_in + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = 2; + usb_value_remask(pintfhdl, &wvalue); + usbctrl_vendorreq(pintfhdl, request, wvalue, index, + &data, len, requesttype); + + _func_exit_; + + return data; + +} + +u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + u16 len; + u32 data=0; + + _func_enter_; + + request = 0x05; + requesttype = 0x01;//read_in + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = 4; +#ifdef CONFIG_RTL8192D + if ((IS_HARDWARE_TYPE_8192DU(pintfhdl->padapter)) && ((addr&0xff000000)>>24 == 0x66)) { + usb_read_reg_rf_byfw(pintfhdl, len, addr, &data); + } else +#endif + { + usb_value_remask(pintfhdl, &wvalue); + usbctrl_vendorreq(pintfhdl, request, wvalue, index, + &data, len, requesttype); + } + + _func_exit_; + + return data; +} + +int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + u16 len; + u8 data; + int ret; + + _func_enter_; + + request = 0x05; + requesttype = 0x00;//write_out + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = 1; + + data = val; + usb_value_remask(pintfhdl, &wvalue); + ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, + &data, len, requesttype); + + _func_exit_; + + return ret; +} + +int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + u16 len; + u16 data; + int ret; + + _func_enter_; + + request = 0x05; + requesttype = 0x00;//write_out + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = 2; + + data = val; + usb_value_remask(pintfhdl, &wvalue); + ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, + &data, len, requesttype); + + _func_exit_; + + return ret; + +} + +int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + u16 len; + u32 data; + int ret; + + _func_enter_; + + request = 0x05; + requesttype = 0x00;//write_out + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = 4; + data =val; + usb_value_remask(pintfhdl, &wvalue); + ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, + &data, len, requesttype); + + _func_exit_; + + return ret; + +} + +int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata) +{ + u8 request; + u8 requesttype; + u16 wvalue; + u16 index; + u16 len; + u8 buf[VENDOR_CMD_MAX_DATA_LEN]={0}; + int ret; + + _func_enter_; + + request = 0x05; + requesttype = 0x00;//write_out + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = length; + _rtw_memcpy(buf, pdata, len ); + usb_value_remask(pintfhdl, &wvalue); + ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, + buf, len, requesttype); + + _func_exit_; + + return ret; + +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_intf.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_intf.c index 9bbacbec539d..811cc3dabcb3 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_intf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/hal_intf.c @@ -43,9 +43,20 @@ void rtw_hal_read_chip_version(_adapter *padapter) void rtw_hal_def_value_init(_adapter *padapter) { - if (is_primary_adapter(padapter)) + if (is_primary_adapter(padapter)) { if(padapter->HalFunc.init_default_value) padapter->HalFunc.init_default_value(padapter); + + rtw_init_hal_com_default_value(padapter); + + { + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); + + /* hal_data..macid_num is ready here */ + dvobj->macid_ctl.num = rtw_min(hal_data->macid_num, MACID_NUM_SW_LIMIT); + } + } } void rtw_hal_free_data(_adapter *padapter) { @@ -56,18 +67,29 @@ void rtw_hal_free_data(_adapter *padapter) if(padapter->HalFunc.free_hal_data) padapter->HalFunc.free_hal_data(padapter); } -void rtw_hal_dm_init(_adapter *padapter) +void rtw_hal_dm_init(_adapter *padapter) { - if (is_primary_adapter(padapter)) + if (is_primary_adapter(padapter)) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + if(padapter->HalFunc.dm_init) padapter->HalFunc.dm_init(padapter); + + _rtw_spinlock_init(&pdmpriv->IQKSpinLock); + } } void rtw_hal_dm_deinit(_adapter *padapter) { - // cancel dm timer - if (is_primary_adapter(padapter)) + if (is_primary_adapter(padapter)) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + if(padapter->HalFunc.dm_deinit) padapter->HalFunc.dm_deinit(padapter); + + _rtw_spinlock_free(&pdmpriv->IQKSpinLock); + } } void rtw_hal_sw_led_init(_adapter *padapter) { @@ -154,8 +176,6 @@ uint rtw_hal_init(_adapter *padapter) if(status == _SUCCESS){ - rtw_hal_init_opmode(padapter); - for (i = 0; iiface_nums; i++) dvobj->padapters[i]->hw_init_completed = _TRUE; @@ -170,6 +190,8 @@ uint rtw_hal_init(_adapter *padapter) rtw_led_control(padapter, LED_CTL_POWER_ON); init_hw_mlme_ext(padapter); + + rtw_hal_init_opmode(padapter); #ifdef CONFIG_RF_GAIN_OFFSET rtw_bb_rf_gain_offset(padapter); @@ -486,20 +508,47 @@ s32 rtw_hal_interrupt_handler(_adapter *padapter) void rtw_hal_set_bwmode(_adapter *padapter, CHANNEL_WIDTH Bandwidth, u8 Offset) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + if(padapter->HalFunc.set_bwmode_handler) + { + ODM_AcquireSpinLock( pDM_Odm, RT_IQK_SPINLOCK); + if(pDM_Odm->RFCalibrateInfo.bIQKInProgress == _TRUE) + DBG_871X_LEVEL(_drv_err_, "%s, %d, IQK may race condition\n", __func__,__LINE__); + ODM_ReleaseSpinLock( pDM_Odm, RT_IQK_SPINLOCK); padapter->HalFunc.set_bwmode_handler(padapter, Bandwidth, Offset); + } } void rtw_hal_set_chan(_adapter *padapter, u8 channel) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + if(padapter->HalFunc.set_channel_handler) + { + ODM_AcquireSpinLock( pDM_Odm, RT_IQK_SPINLOCK); + if(pDM_Odm->RFCalibrateInfo.bIQKInProgress == _TRUE) + DBG_871X_LEVEL(_drv_err_, "%s, %d, IQK may race condition\n", __func__,__LINE__); + ODM_ReleaseSpinLock( pDM_Odm, RT_IQK_SPINLOCK); padapter->HalFunc.set_channel_handler(padapter, channel); + } } void rtw_hal_set_chnl_bw(_adapter *padapter, u8 channel, CHANNEL_WIDTH Bandwidth, u8 Offset40, u8 Offset80) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + if(padapter->HalFunc.set_chnl_bw_handler) + { + ODM_AcquireSpinLock( pDM_Odm, RT_IQK_SPINLOCK); + if(pDM_Odm->RFCalibrateInfo.bIQKInProgress == _TRUE) + DBG_871X_LEVEL(_drv_err_, "%s, %d, IQK may race condition\n", __func__,__LINE__); + ODM_ReleaseSpinLock( pDM_Odm, RT_IQK_SPINLOCK); padapter->HalFunc.set_chnl_bw_handler(padapter, channel, Bandwidth, Offset40, Offset80); + } } void rtw_hal_set_tx_power_level(_adapter *padapter, u8 channel) @@ -710,37 +759,50 @@ s32 rtw_hal_is_disable_sw_channel_plan(PADAPTER padapter) return GET_HAL_DATA(padapter)->bDisableSWChannelPlan; } -s32 rtw_hal_macid_sleep(PADAPTER padapter, u32 macid) +s32 rtw_hal_macid_sleep(PADAPTER padapter, u8 macid) { + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); u8 support; - support = _FALSE; rtw_hal_get_def_var(padapter, HAL_DEF_MACID_SLEEP, &support); if (_FALSE == support) return _FAIL; - rtw_hal_set_hwreg(padapter, HW_VAR_MACID_SLEEP, (u8*)&macid); + if (macid >= macid_ctl->num) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT": Invalid macid(%u)\n", + FUNC_ADPT_ARG(padapter), macid); + return _FAIL; + } + + rtw_hal_set_hwreg(padapter, HW_VAR_MACID_SLEEP, &macid); return _SUCCESS; } -s32 rtw_hal_macid_wakeup(PADAPTER padapter, u32 macid) +s32 rtw_hal_macid_wakeup(PADAPTER padapter, u8 macid) { + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); u8 support; - support = _FALSE; rtw_hal_get_def_var(padapter, HAL_DEF_MACID_SLEEP, &support); if (_FALSE == support) return _FAIL; - rtw_hal_set_hwreg(padapter, HW_VAR_MACID_WAKEUP, (u8*)&macid); + if (macid >= macid_ctl->num) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT": Invalid macid(%u)\n", + FUNC_ADPT_ARG(padapter), macid); + return _FAIL; + } + + rtw_hal_set_hwreg(padapter, HW_VAR_MACID_WAKEUP, &macid); return _SUCCESS; } -#ifdef CONFIG_BT_COEXIST s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) { s32 ret = _FAIL; @@ -750,10 +812,9 @@ s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBu else { DBG_871X("%s: func[fill_h2c_cmd] not defined!\n", __FUNCTION__); + rtw_warn_on(1); } return ret; } -#endif // CONFIG_BT_COEXIST - diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/led/hal_usb_led.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/led/hal_usb_led.c index 7f172212b82e..6706e0101c86 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/led/hal_usb_led.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/led/hal_usb_led.c @@ -1237,6 +1237,7 @@ SwLedBlink9( SwLedOff(Adapter, pLed); RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); } + //DBG_871X("%s, pLed->CurrLedState=%d, pLed->BlinkingLedState=%d \n", __FUNCTION__, pLed->CurrLedState, pLed->BlinkingLedState); switch(pLed->CurrLedState) @@ -1260,8 +1261,8 @@ SwLedBlink9( case LED_BLINK_StartToBlink: if( pLed->bLedOn ) { - pLed->BlinkingLedState = RTW_LED_OFF; - _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); } else { @@ -1286,7 +1287,7 @@ SwLedBlink9( else if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { pLed->bLedLinkBlinkInProgress = _TRUE; - pLed->CurrLedState = LED_BLINK_ALWAYS_ON; + pLed->CurrLedState = LED_BLINK_SLOWLY; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); @@ -1336,8 +1337,7 @@ SwLedBlink9( } else { - pLed->bLedNoLinkBlinkInProgress = _TRUE; - pLed->CurrLedState = LED_BLINK_ALWAYS_ON; + pLed->CurrLedState = LED_BLINK_SLOWLY; if( pLed->bLedOn ) pLed->BlinkingLedState = RTW_LED_OFF; else @@ -3879,7 +3879,7 @@ SwLedControlMode9( PLED_USB pLed1 = &(ledpriv->SwLed1); PLED_USB pLed2 = &(ledpriv->SwLed2); BOOLEAN bWPSOverLap = _FALSE; - + //DBG_871X("LedAction=%d \n", LedAction); switch(LedAction) { case LED_CTL_START_TO_LINK: @@ -3980,7 +3980,7 @@ SwLedControlMode9( if(LedAction == LED_CTL_LINK) { pLed->BlinkingLedState = RTW_LED_ON; - pLed->CurrLedState = LED_BLINK_ALWAYS_ON; + pLed->CurrLedState = LED_BLINK_SLOWLY; } else { @@ -4068,7 +4068,7 @@ SwLedControlMode9( pLed2->CurrLedState = LED_BLINK_LINK_IN_PROCESS; pLed2->bLedWPSBlinkInProgress = _TRUE; - _set_timer(&(pLed2->BlinkTimer), 0); + _set_timer(&(pLed2->BlinkTimer), 500); break; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_cmd.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_cmd.c index 635a41985c2e..7714e38b448e 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_cmd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_cmd.c @@ -546,11 +546,15 @@ static void ConstructPnoInfo( u8 *pPnoInfoPkt = pframe; pPnoInfoPkt = (u8*)(pframe+ *pLength); - _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 4); + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1); - *pLength+=4; - pPnoInfoPkt += 4; - _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 4); + *pLength+=1; + pPnoInfoPkt += 1; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1); + + *pLength+=3; + pPnoInfoPkt += 3; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1); *pLength+=4; pPnoInfoPkt += 4; @@ -577,6 +581,11 @@ static void ConstructPnoInfo( *pLength+=MAX_PNO_LIST_COUNT; pPnoInfoPkt += MAX_PNO_LIST_COUNT; + _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, + MAX_HIDDEN_AP); + + *pLength+=MAX_HIDDEN_AP; + pPnoInfoPkt += MAX_HIDDEN_AP; } static void ConstructSSIDList( @@ -776,7 +785,8 @@ static void ConstructGTKResponse( #endif //CONFIG_GTK_OL #ifdef CONFIG_PNO_SUPPORT -static void ConstructProbeReq(_adapter *padapter, u8 *pframe, u32 *pLength) +static void ConstructProbeReq(_adapter *padapter, u8 *pframe, u32 *pLength, + pno_ssid_t *ssid) { struct rtw_ieee80211_hdr *pwlanhdr; u16 *fctrl; @@ -796,7 +806,6 @@ static void ConstructProbeReq(_adapter *padapter, u8 *pframe, u32 *pLength) fctrl = &(pwlanhdr->frame_ctl); *(fctrl) = 0; - //broadcast probe request frame _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN); @@ -808,7 +817,11 @@ static void ConstructProbeReq(_adapter *padapter, u8 *pframe, u32 *pLength) pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); pframe += pktlen; - pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen); + if (ssid == NULL) { + pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen); + } else { + pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen); + } get_rate_set(padapter, bssrate, &bssrate_len); @@ -1013,6 +1026,25 @@ CheckFwRsvdPageContent( } } +// +// Description: Get the reserved page number in Tx packet buffer. +// Retrun value: the page number. +// 2012.08.09, by tynli. +// +u8 GetTxBufferRsvdPageNum8723B(_adapter *padapter, bool wowlan) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 RsvdPageNum=0; + // default reseved 1 page for the IC type which is undefined. + u8 TxPageBndy= LAST_ENTRY_OF_TX_PKT_BUFFER_8723B; + + rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy); + + RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8723B -TxPageBndy + 1; + + return RsvdPageNum; +} + static void rtl8723b_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc) { u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0}; @@ -1128,7 +1160,12 @@ void rtl8723b_set_FwMediaStatusRpt_cmd(PADAPTER padapter, u8 mstatus, u8 macid) static void rtl8723b_set_FwKeepAlive_cmd(PADAPTER padapter, u8 benable, u8 pkt_type) { u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0}; - u8 adopt = 1, check_period = 5; + u8 adopt = 1; +#ifdef CONFIG_PLATFORM_INTEL_BYT + u8 check_period = 10; +#else + u8 check_period = 5; +#endif DBG_871X("%s(): benable = %d\n", __func__, benable); SET_8723B_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, benable); @@ -1159,6 +1196,7 @@ static void rtl8723b_set_FwDisconDecision_cmd(PADAPTER padapter, u8 benable) void rtl8723b_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask) { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); u8 u1H2CMacIdConfigParm[H2C_MACID_CFG_LEN]={0}; DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask); @@ -1169,6 +1207,21 @@ _func_enter_; SET_8723B_H2CCMD_MACID_CFG_RAID(u1H2CMacIdConfigParm, raid); SET_8723B_H2CCMD_MACID_CFG_SGI_EN(u1H2CMacIdConfigParm, (sgi)? 1:0); SET_8723B_H2CCMD_MACID_CFG_BW(u1H2CMacIdConfigParm, bw); + + //DisableTXPowerTraining + if(pHalData->bDisableTXPowerTraining){ + SET_8723B_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm,1); + DBG_871X("%s,Disable PWT by driver\n",__FUNCTION__); + } + else{ + PDM_ODM_T pDM_OutSrc = &pHalData->odmpriv; + + if(pDM_OutSrc->bDisablePowerTraining){ + SET_8723B_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm,1); + DBG_871X("%s,Disable PWT by DM\n",__FUNCTION__); + } + } + SET_8723B_H2CCMD_MACID_CFG_RATE_MASK0(u1H2CMacIdConfigParm, (u8)(mask & 0x000000ff)); SET_8723B_H2CCMD_MACID_CFG_RATE_MASK1(u1H2CMacIdConfigParm, (u8)((mask & 0x0000ff00) >>8)); SET_8723B_H2CCMD_MACID_CFG_RATE_MASK2(u1H2CMacIdConfigParm, (u8)((mask & 0x00ff0000) >> 16)); @@ -1218,54 +1271,69 @@ void rtl8723b_set_FwAPReqRPT_cmd(PADAPTER padapter, u32 need_ack) void rtl8723b_set_FwPwrMode_cmd(PADAPTER padapter, u8 psmode) { int i; + u8 smart_ps = 0; struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; u8 u1H2CPwrModeParm[H2C_PWRMODE_LEN]={0}; u8 PowerState=0, awake_intvl = 1, byte5 = 0, rlbm = 0; +#ifdef CONFIG_P2P struct wifidirect_info *wdinfo = &(padapter->wdinfo); +#endif // CONFIG_P2P _func_enter_; +#ifdef CONFIG_PLATFORM_INTEL_BYT + if(psmode == PS_MODE_DTIM) + psmode = PS_MODE_MAX; +#endif //CONFIG_PLATFORM_INTEL_BYT + + if(pwrpriv->dtim > 0) DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d, dtim=%d\n", __func__, psmode, pwrpriv->smart_ps, pwrpriv->dtim); else DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d\n", __func__, psmode, pwrpriv->smart_ps); -#ifdef CONFIG_WOWLAN - if(psmode == PS_MODE_DTIM) //For WOWLAN LPS, DTIM = (awake_intvl - 1) + if(psmode == PS_MODE_MIN) { -#ifdef CONFIG_PLATFORM_ARM_SUN8I - awake_intvl = 4;//DTIM=3 -#else - awake_intvl = 3;//DTIM=2 -#endif - rlbm = 2; + rlbm = 0; + awake_intvl = 2; + smart_ps = pwrpriv->smart_ps; } - else -#endif //CONFIG_WOWLAN + else if(psmode == PS_MODE_MAX) + { + rlbm = 1; + awake_intvl = 2; + smart_ps = pwrpriv->smart_ps; + } + else if(psmode == PS_MODE_DTIM) //For WOWLAN LPS, DTIM = (awake_intvl - 1) { if(pwrpriv->dtim > 0 && pwrpriv->dtim < 16) awake_intvl = pwrpriv->dtim+1;//DTIM = (awake_intvl - 1) else -#ifdef CONFIG_PLATFORM_ARM_SUN8I awake_intvl = 4;//DTIM=3 -#else - awake_intvl = 3;//DTIM=2 -#endif + rlbm = 2; + smart_ps = pwrpriv->smart_ps; + } + else + { + rlbm = 2; + awake_intvl = 4; + smart_ps = pwrpriv->smart_ps; } - +#ifdef CONFIG_P2P if (!rtw_p2p_chk_state(wdinfo, P2P_STATE_NONE)) { awake_intvl = 2; - rlbm = 2; + rlbm = 1; } +#endif // CONFIG_P2P if(padapter->registrypriv.wifi_spec==1) { awake_intvl = 2; - rlbm = 2; + rlbm = 1; } if (psmode > 0) @@ -1298,7 +1366,7 @@ _func_enter_; } SET_8723B_H2CCMD_PWRMODE_PARM_MODE(u1H2CPwrModeParm, (psmode>0)?1:0); - SET_8723B_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CPwrModeParm, pwrpriv->smart_ps); + SET_8723B_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CPwrModeParm, smart_ps); SET_8723B_H2CCMD_PWRMODE_PARM_RLBM(u1H2CPwrModeParm, rlbm); SET_8723B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CPwrModeParm, awake_intvl); SET_8723B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CPwrModeParm, padapter->registrypriv.uapsd_enable); @@ -1319,14 +1387,14 @@ _func_enter_; pmlmeext->DrvBcnEarly = 0xff; pmlmeext->DrvBcnTimeOut = 0xff; - DBG_871X("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt); + //DBG_871X("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt); for(i=0; i<9; i++) { pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) /pmlmeext->bcn_cnt; - DBG_871X("%s(): bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d] = %d\n", __func__, i, pmlmeext->bcn_delay_cnt[i] - ,i ,pmlmeext->bcn_delay_ratio[i]); + //DBG_871X("%s(): bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d] = %d\n", __func__, i, pmlmeext->bcn_delay_cnt[i] + // ,i ,pmlmeext->bcn_delay_ratio[i]); ratio_20_delay += pmlmeext->bcn_delay_ratio[i]; ratio_80_delay += pmlmeext->bcn_delay_ratio[i]; @@ -1334,13 +1402,13 @@ _func_enter_; if(ratio_20_delay > 20 && pmlmeext->DrvBcnEarly == 0xff) { pmlmeext->DrvBcnEarly = i; - DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly); + //DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly); } if(ratio_80_delay > 80 && pmlmeext->DrvBcnTimeOut == 0xff) { pmlmeext->DrvBcnTimeOut = i; - DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut); + //DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut); } //reset adaptive_early_32k cnt @@ -1355,8 +1423,8 @@ _func_enter_; } else { - DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly); - DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut); + //DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly); + //DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut); } /* offload to FW if fw version > v15.10 @@ -1438,50 +1506,6 @@ void rtl8723b_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param) } #ifdef CONFIG_WOWLAN -static void rtl8723b_set_FwWoWlanCtrl_Cmd(PADAPTER padapter, u8 bFuncEn) -{ - struct security_priv *psecpriv = &padapter->securitypriv; - struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter); - u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN]={0}; - u8 discont_wake = 1, gpionum = 0, gpio_dur = 0, hw_unicast = 0, gpio_pulse_cnt=100; - u8 sdio_wakeup_enable = 1; - u8 gpio_high_active = 0; //0: low active, 1: high active - u8 magic_pkt = 0; - -#ifdef CONFIG_GPIO_WAKEUP - gpionum = WAKEUP_GPIO_IDX; - sdio_wakeup_enable = 0; -#endif - -#ifdef CONFIG_PNO_SUPPORT - if (!ppwrpriv->wowlan_pno_enable) { - magic_pkt = 1; - } -#endif - - if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_) - hw_unicast = 1; - - DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn); - - SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, bFuncEn); - SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, 0); - SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt); - SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast); - SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0); - SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active); - SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake); - SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum); - SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable); - SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur); - //SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, 1); - SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, 0x09); - - RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CWoWlanCtrlParm:", u1H2CWoWlanCtrlParm, H2C_WOWLAN_LEN); - - FillH2CCmd8723B(padapter, H2C_8723B_WOWLAN, H2C_WOWLAN_LEN, u1H2CWoWlanCtrlParm); -} - static void rtl8723b_set_FwRemoteWakeCtrl_Cmd(PADAPTER padapter, u8 benable) { u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN]={0}; @@ -1575,98 +1599,6 @@ static void rtl8723b_set_FwScanOffloadInfo_cmd(PADAPTER padapter, PRSVDPAGE_LOC } #endif //CONFIG_PNO_SUPPORT -#if 0 -void dump_TX_FIFO(_adapter* padapter){ - int i; - u8 val = 0 ; - u8 base = 0; - u32 addr = 0; - - DBG_871X("+%s+\n", __func__); - val = rtw_read8(padapter, 0x106); - rtw_write8(padapter, 0x106, 0x69); - DBG_871X("0x106: 0x%02x\n", val); - base = rtw_read8(padapter, 0x209); - DBG_871X("0x209: 0x%02x\n", base); - - DBG_871X("beacon:\n"); - addr = ((base)*128)/8; - for (i = 0 ; i < 32 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } - - DBG_871X("probe_response:\n"); - addr = ((base + 2)*128)/8; - for (i = 0 ; i < 48 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } -#if 0 - DBG_871X("GTK Info:\n"); - addr = ((base + 8)*128)/8; - for (i = 0 ; i < 4 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } - - DBG_871X("GTK Rsp:\n"); - addr = ((base + 9)*128)/8; - for (i = 0 ; i < 32 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } -#endif -#if 0 - DBG_871X("probe request:\n"); - addr = ((base + 6)*128)/8; - for (i = 0 ; i < 16 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } - - DBG_871X("PNO_INFO:\n"); - addr = ((base + 7)*128)/8; - for (i = 0 ; i < 16 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } - - DBG_871X("SSID_INFO:\n"); - addr = ((base + 8)*128)/8; - for (i = 0 ; i < 16 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } - - DBG_871X("SCAN_INFO:\n"); - addr = ((base + 9)*128)/8; - for (i = 0 ; i < 16 ; i+=2) { - rtw_write32(padapter, 0x140, addr + i); - printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - rtw_write32(padapter, 0x140, addr + i + 1); - printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); - } -#endif - rtw_write8(padapter, 0x106, val); - DBG_871X("-%s-\n", __func__); -} -#endif - static void rtl8723b_set_FwWoWlanRelated_cmd(_adapter* padapter, u8 enable) { struct security_priv *psecpriv = &padapter->securitypriv; @@ -1704,7 +1636,7 @@ _func_enter_; rtw_msleep_os(2); } - rtl8723b_set_FwWoWlanCtrl_Cmd(padapter, enable); + rtw_hal_set_wowlan_ctrl_cmd(padapter, enable); rtw_msleep_os(2); rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable); @@ -1712,11 +1644,15 @@ _func_enter_; else { #if 0 - dump_TX_FIFO(padapter, 11, 128); + { + u32 PageSize = 0; + rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize); + dump_TX_FIFO(padapter, 4, PageSize); + } #endif rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable); - rtw_msleep_os(2); - rtl8723b_set_FwWoWlanCtrl_Cmd(padapter, enable); + rtw_msleep_os(2); + rtw_hal_set_wowlan_ctrl_cmd(padapter, enable); } _func_exit_; @@ -1868,6 +1804,10 @@ static void rtl8723b_set_FwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished) u8 kek[RTW_KEK_LEN]; u8 kck[RTW_KCK_LEN]; #endif +#ifdef CONFIG_PNO_SUPPORT + int index; + u8 ssid_num; +#endif //CONFIG_PNO_SUPPORT #endif #ifdef DBG_CONFIG_ERROR_DETECT struct sreset_priv *psrtpriv; @@ -2141,27 +2081,31 @@ static void rtl8723b_set_FwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished) { #ifdef CONFIG_PNO_SUPPORT if (pwrctl->pno_in_resume == _FALSE && pwrctl->pno_inited == _TRUE) { - //Probe Request + + //Broadcast Probe Request RsvdPageLoc.LocProbePacket = TotalPageNum; + ConstructProbeReq( padapter, &ReservedPagePacket[BufIndex], - &ProbeReqLength); + &ProbeReqLength, + NULL); rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeReqLength, _FALSE, _FALSE, _FALSE); + #ifdef CONFIG_PNO_SET_DEBUG - { - int gj; - printk("probe req pkt=> \n"); - for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) { - printk(" %02x ",ReservedPagePacket[BufIndex- TxDescLen + gj]); - if ((gj + 1)%8==0) - printk("\n"); + { + int gj; + printk("probe req pkt=> \n"); + for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) { + printk(" %02x ",ReservedPagePacket[BufIndex- TxDescLen + gj]); + if ((gj + 1)%8==0) + printk("\n"); + } + printk(" <=end\n"); } - printk(" <=end\n"); - } #endif CurtPktPageNum = (u8)PageNum_128(TxDescLen + ProbeReqLength); @@ -2170,6 +2114,42 @@ static void rtl8723b_set_FwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished) BufIndex += (CurtPktPageNum*PageSize); + //Hidden SSID Probe Request + ssid_num = pwrctl->pnlo_info->hidden_ssid_num; + + for (index = 0 ; index < ssid_num ; index++) { + pwrctl->pnlo_info->loc_probe_req[index] = TotalPageNum; + + ConstructProbeReq( + padapter, + &ReservedPagePacket[BufIndex], + &ProbeReqLength, + &pwrctl->pno_ssid_list->node[index]); + + rtl8723b_fill_fake_txdesc(padapter, + &ReservedPagePacket[BufIndex-TxDescLen], + ProbeReqLength, _FALSE, _FALSE, _FALSE); + +#ifdef CONFIG_PNO_SET_DEBUG + { + int gj; + printk("probe req pkt=> \n"); + for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) { + printk(" %02x ", ReservedPagePacket[BufIndex- TxDescLen + gj]); + if ((gj + 1)%8==0) + printk("\n"); + } + printk(" <=end\n"); + } +#endif + CurtPktPageNum = + (u8)PageNum_128(TxDescLen + ProbeReqLength); + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + } + //PNO INFO Page RsvdPageLoc.LocPNOInfo = TotalPageNum; ConstructPnoInfo(padapter, &ReservedPagePacket[BufIndex -TxDescLen], &PNOLength); @@ -2248,7 +2228,7 @@ static void rtl8723b_set_FwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished) // update attribute pattrib = &pcmdframe->attrib; update_mgntframe_attrib(padapter, pattrib); - pattrib->qsel = 0x10; + pattrib->qsel = QSLT_BEACON; pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset; #ifdef CONFIG_PCI_HCI dump_mgntframe(padapter, pcmdframe); @@ -2393,7 +2373,7 @@ static void rtl8723b_set_AP_FwRsvdPagePkt(PADAPTER padapter, // update attribute pattrib = &pcmdframe->attrib; update_mgntframe_attrib(padapter, pattrib); - pattrib->qsel = 0x10; + pattrib->qsel = QSLT_BEACON; pattrib->pktlen = TotalPacketLen - TxDescOffset; pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset; #ifdef CONFIG_PCI_HCI @@ -2518,9 +2498,11 @@ _func_enter_; } // Clear CR[8] or beacon packet will not be send to TxBuf anymore. +#ifndef CONFIG_PCI_HCI v8 = rtw_read8(padapter, REG_CR+1); v8 &= ~BIT(0); // ~ENSWBCN rtw_write8(padapter, REG_CR+1, v8); +#endif } _func_exit_; @@ -2734,7 +2716,7 @@ static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter) // update attribute pattrib = &pcmdframe->attrib; update_mgntframe_attrib(padapter, pattrib); - pattrib->qsel = 0x10; + pattrib->qsel = QSLT_BEACON; pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset; #ifdef CONFIG_PCI_HCI dump_mgntframe(padapter, pcmdframe); @@ -2858,9 +2840,11 @@ void rtl8723b_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter) } // Clear CR[8] or beacon packet will not be send to TxBuf anymore. +#ifndef CONFIG_PCI_HCI val8 = rtw_read8(padapter, REG_CR+1); val8 &= ~BIT(0); // ~ENSWBCN rtw_write8(padapter, REG_CR+1, val8); +#endif } #endif // CONFIG_BT_COEXIST diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_dm.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_dm.c index d209d768702d..2224afb83615 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_dm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_dm.c @@ -244,20 +244,13 @@ dm_InitGPIOSetting( //============================================================ static void Init_ODM_ComInfo_8723b(PADAPTER Adapter) { - PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); struct dm_priv *pdmpriv = &pHalData->dmpriv; u8 cut_ver,fab_ver; - // - // Init Value - // - _rtw_memset(pDM_Odm,0,sizeof(*pDM_Odm)); + Init_ODM_ComInfo(Adapter); - pDM_Odm->Adapter = Adapter; - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_PLATFORM,ODM_CE); - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_INTERFACE,Adapter->interface_type);//RTL871X_HCI_TYPE ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PACKAGE_TYPE, pHalData->PackageType); ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_IC_TYPE, ODM_RTL8723B); @@ -267,30 +260,6 @@ static void Init_ODM_ComInfo_8723b(PADAPTER Adapter) DBG_871X("%s(): fab_ver=%d cut_ver=%d\n", __func__, fab_ver, cut_ver); ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_FAB_VER,fab_ver); ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_CUT_VER,cut_ver); - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_MP_TEST_CHIP,IS_NORMAL_CHIP(pHalData->VersionID)); - -#ifdef CONFIG_USB_HCI - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_BOARD_TYPE,pHalData->BoardType); - - if(pHalData->BoardType == BOARD_USB_High_PA){ - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_EXT_LNA,_TRUE); - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_EXT_PA,_TRUE); - } -#endif - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_PATCH_ID,pHalData->CustomerID); - // ODM_CMNINFO_BINHCT_TEST only for MP Team - ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_BWIFI_TEST,Adapter->registrypriv.wifi_spec); - - - if(pHalData->rf_type == RF_1T1R){ - ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_RF_TYPE,ODM_1T1R); - } - else if(pHalData->rf_type == RF_2T2R){ - ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_RF_TYPE,ODM_2T2R); - } - else if(pHalData->rf_type == RF_1T2R){ - ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_RF_TYPE,ODM_1T2R); - } #ifdef CONFIG_DISABLE_ODM pdmpriv->InitODMFlag = 0; @@ -307,13 +276,9 @@ static void Init_ODM_ComInfo_8723b(PADAPTER Adapter) static void Update_ODM_ComInfo_8723b(PADAPTER Adapter) { - struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; - struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; - struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter); PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); struct dm_priv *pdmpriv = &pHalData->dmpriv; - int i; pdmpriv->InitODMFlag = 0 | ODM_BB_DIG @@ -327,6 +292,8 @@ static void Update_ODM_ComInfo_8723b(PADAPTER Adapter) | ODM_MAC_EDCA_TURBO | ODM_RF_TX_PWR_TRACK | ODM_RF_CALIBRATION + | ODM_BB_NHM_CNT +// | ODM_BB_PWR_TRAIN ; if (rtw_odm_adaptivity_needed(Adapter) == _TRUE) @@ -350,48 +317,7 @@ static void Update_ODM_ComInfo_8723b(PADAPTER Adapter) pdmpriv->InitODMFlag = 0; #endif//CONFIG_DISABLE_ODM - // - // Pointer reference - // - //ODM_CMNINFO_MAC_PHY_MODE pHalData->MacPhyMode92D - // ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_MAC_PHY_MODE,&(pDM_Odm->u1Byte_temp)); - ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,pdmpriv->InitODMFlag); - - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_TX_UNI,&(Adapter->xmitpriv.tx_bytes)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_RX_UNI,&(Adapter->recvpriv.rx_bytes)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_WM_MODE,&(pmlmeext->cur_wireless_mode)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_SEC_CHNL_OFFSET,&(pHalData->nCur40MhzPrimeSC)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_SEC_MODE,&(Adapter->securitypriv.dot11PrivacyAlgrthm)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BW,&(pHalData->CurrentChannelBW )); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_CHNL,&( pHalData->CurrentChannel)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_NET_CLOSED,&( Adapter->net_closed)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_MP_MODE,&(Adapter->registrypriv.mp_mode)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BAND,&(pHalData->CurrentBandType)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_FORCED_IGI_LB,&(pHalData->u1ForcedIgiLb)); - //================= only for 8192D ================= - /* - //pHalData->CurrentBandType92D - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BAND,&(pDM_Odm->u1Byte_temp)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_DMSP_GET_VALUE,&(pDM_Odm->u1Byte_temp)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BUDDY_ADAPTOR,&(pDM_Odm->PADAPTER_temp)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_DMSP_IS_MASTER,&(pDM_Odm->u1Byte_temp)); - //================= only for 8192D ================= - // driver havn't those variable now - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BT_OPERATION,&(pDM_Odm->u1Byte_temp)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_BT_DISABLE_EDCA,&(pDM_Odm->u1Byte_temp)); - */ - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_FORCED_RATE,&(pHalData->ForcedDataRate)); - - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_SCAN,&(pmlmepriv->bScanInProcess)); - ODM_CmnInfoHook(pDM_Odm,ODM_CMNINFO_POWER_SAVING,&(pwrctrlpriv->bpower_saving)); - - - for(i=0; i< NUM_STA; i++) - { - //pDM_Odm->pODM_StaInfo[i] = NULL; - ODM_CmnInfoPtrArrayHook(pDM_Odm, ODM_CMNINFO_STA_STATUS,i,NULL); - } } void @@ -723,11 +649,7 @@ void rtl8723b_init_dm_priv(IN PADAPTER Adapter) PDM_ODM_T podmpriv = &pHalData->odmpriv; _rtw_memset(pdmpriv, 0, sizeof(struct dm_priv)); Init_ODM_ComInfo_8723b(Adapter); -#ifdef CONFIG_SW_ANTENNA_DIVERSITY - //_init_timer(&(pdmpriv->SwAntennaSwitchTimer), Adapter->pnetdev , odm_SW_AntennaSwitchCallback, Adapter); ODM_InitAllTimers(podmpriv ); -#endif - } void rtl8723b_deinit_dm_priv(IN PADAPTER Adapter) @@ -735,9 +657,7 @@ void rtl8723b_deinit_dm_priv(IN PADAPTER Adapter) PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; PDM_ODM_T podmpriv = &pHalData->odmpriv; -#ifdef CONFIG_SW_ANTENNA_DIVERSITY - //_cancel_timer_ex(&pdmpriv->SwAntennaSwitchTimer); ODM_CancelAllTimers(podmpriv); -#endif + } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_hal_init.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_hal_init.c index 09ff86cadbfd..37cb5cc5fb66 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_hal_init.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_hal_init.c @@ -270,7 +270,8 @@ void _8051Reset8723(PADAPTER padapter) u8 cpu_rst; u8 io_rst; - + io_rst = rtw_read8(padapter, REG_RSV_CTRL); + rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1)); // Reset 8051(WLMCU) IO wrapper // 0x1c[8] = 0 // Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624 @@ -282,6 +283,8 @@ void _8051Reset8723(PADAPTER padapter) cpu_rst &= ~BIT(2); rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst); + io_rst = rtw_read8(padapter, REG_RSV_CTRL); + rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1)); // Enable 8051 IO wrapper // 0x1c[8] = 1 io_rst = rtw_read8(padapter, REG_RSV_CTRL+1); @@ -295,7 +298,6 @@ void _8051Reset8723(PADAPTER padapter) DBG_8192C("%s: Finish\n", __FUNCTION__); } -extern u8 g_fwdl_chksum_fail; static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms) { s32 ret = _FAIL; @@ -316,11 +318,8 @@ static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms) goto exit; } - if (g_fwdl_chksum_fail) { - DBG_871X("%s: fwdl test case: fwdl_chksum_fail\n", __FUNCTION__); - g_fwdl_chksum_fail--; + if (rtw_fwdl_test_trigger_chksum_fail()) goto exit; - } ret = _SUCCESS; @@ -331,7 +330,6 @@ exit: return ret; } -extern u8 g_fwdl_wintint_rdy_fail; static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms) { s32 ret = _FAIL; @@ -359,11 +357,8 @@ static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms) goto exit; } - if (g_fwdl_wintint_rdy_fail) { - DBG_871X("%s: fwdl test case: wintint_rdy_fail\n", __FUNCTION__); - g_fwdl_wintint_rdy_fail--; + if (rtw_fwdl_test_trigger_wintint_rdy_fail()) goto exit; - } ret = _SUCCESS; @@ -450,6 +445,9 @@ int _WriteBTFWtoTxPktBuf8723B( struct pkt_attrib *pattrib; u8 txdesc_offset = TXDESC_OFFSET; u8 val8; +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) + u8 u1bTmp; +#endif #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE) TotalPktLen = FwBufLen; @@ -483,7 +481,7 @@ int _WriteBTFWtoTxPktBuf8723B( // 1. Pause BCN //--------------------------------------------------------- //Set REG_CR bit 8. DMA beacon by SW. -#if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE) +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR+1); PlatformEFIOWrite1Byte(Adapter, REG_CR+1, (u1bTmp|BIT0)); #else @@ -909,11 +907,11 @@ s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware) pBTFirmwareBuf = (u8*)Rtl8723BFwBTImgArray; BTFirmwareLen = Rtl8723BFwBTImgArrayLength; + pFirmware->szFwBuffer = pBTFirmwareBuf; + pFirmware->ulFwLength = BTFirmwareLen; #endif // CONFIG_EMBEDDED_FWIMG } - pFirmware->szFwBuffer = pBTFirmwareBuf; - pFirmware->ulFwLength = BTFirmwareLen; DBG_8192C("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen); // for h2c cam here should be set to true @@ -1015,6 +1013,9 @@ s32 rtl8723b_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw) pdbgpriv->dbg_downloadfw_pwr_state_cnt++; } } + + rtw_btcoex_PreLoadFirmware(padapter); + #ifdef CONFIG_FILE_FWIMG #ifdef CONFIG_WOWLAN if (bUsedWoWLANFw) @@ -3238,6 +3239,30 @@ void UpdateHalRAMask8723B(PADAPTER padapter, u32 mac_id, u8 rssi_level) DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x init_rate=0x%x\n", __func__, mac_id, psta->raid, psta->bw_mode, mask, psta->init_rate); } +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc) +{ + u16 *usPtr = (u16*)ptxdesc; + u32 count; + u32 index; + u16 checksum = 0; + + + // Clear first + ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); + + // checksume is always calculated by first 32 bytes, + // and it doesn't depend on TX DESC length. + // Thomas,Lucas@SD4,20130515 + count = 16; + + for (index = 0; index < count; index++) { + checksum ^= le16_to_cpu(*(usPtr + index)); + } + + ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff); +} +#endif void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc) { @@ -3259,8 +3284,11 @@ void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc) pHalFunc->hal_dm_watchdog = &rtl8723b_HalDmWatchDog; pHalFunc->hal_dm_watchdog_in_lps = &rtl8723b_HalDmWatchDog_in_LPS; - +#ifdef CONFIG_C2H_PACKET_EN + pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8723B; +#endif // CONFIG_C2H_PACKET_EN + pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723b_SetBeaconRelatedRegisters; pHalFunc->Add_RateATid = &rtl8723b_Add_RateATid; @@ -3304,9 +3332,14 @@ void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc) pHalFunc->c2h_handler = c2h_handler_8723b; pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723b; -#ifdef CONFIG_BT_COEXIST pHalFunc->fill_h2c_cmd = &FillH2CCmd8723B; -#endif // CONFIG_BT_COEXIST +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pHalFunc->hal_cal_txdesc_chksum = &rtl8723b_cal_txdesc_chksum; +#endif +#ifdef CONFIG_WOWLAN + pHalFunc->hal_set_wowlan_fw = &SetFwRelatedForWoWLAN8723b; +#endif + pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8723B; } void rtl8723b_InitAntenna_Selection(PADAPTER padapter) @@ -3370,7 +3403,9 @@ void rtl8723b_init_default_value(PADAPTER padapter) if (!adapter_to_pwrctl(padapter)->bkeepfwalive) pHalData->LastHMEBoxNum = 0; - pHalData->bIQKInitialized = _FALSE; + /* hal capability values */ + pHalData->macid_num = MACID_NUM_8723B; + pHalData->cam_entry_num = CAM_ENTRY_NUM_8723B; // init dm default value pdmpriv->TM_Trigger = 0;//for IQK @@ -4258,6 +4293,10 @@ Hal_EfuseParseBTCoexistInfo_8723B( #endif } +#ifdef CONFIG_FOR_RTL8723BS_VQ0 + pHalData->ant_path = ODM_RF_PATH_B;//s0 +#endif + #ifdef CONFIG_BT_COEXIST if (padapter->registrypriv.ant_num > 0) { DBG_8192C("%s: Apply driver defined antenna number(%d) to replace origin(%d)\n", @@ -4418,7 +4457,7 @@ Hal_EfuseParseAntennaDiversity_8723B( ) { #ifdef CONFIG_ANTENNA_DIVERSITY - HAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); struct registry_priv *registry_par = &pAdapter->registrypriv; if (pHalData->EEPROMBluetoothAntNum == Ant_x1){ @@ -4426,49 +4465,31 @@ Hal_EfuseParseAntennaDiversity_8723B( } else{ if(registry_par->antdiv_cfg == 2)// 0:OFF , 1:ON, 2:By EFUSE - pHalData->AntDivCfg = 0; + pHalData->AntDivCfg = 1; else pHalData->AntDivCfg = registry_par->antdiv_cfg; } - //if (REGISTRY(pAdapter,bEfusePriorityAuto) == TRUE) - if(registry_par->antdiv_type == 0)// If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. - { + // If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. + if(registry_par->antdiv_type == 0) { pHalData->TRxAntDivType = hwinfo[EEPROM_RFE_OPTION_8723B]; if (pHalData->TRxAntDivType == 0xFF) pHalData->TRxAntDivType = S0S1_SW_ANTDIV;//GetRegAntDivType(pAdapter); else if (pHalData->TRxAntDivType == 0x10) pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1 - else if (pHalData->TRxAntDivType == 0x11) + else if (pHalData->TRxAntDivType == 0x11) pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1 - //pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; //DPDT - + else + DBG_8192C("%s: efuse[0x%x]=0x%02x is unknown type\n", + __FUNCTION__, EEPROM_RFE_OPTION_8723B, pHalData->TRxAntDivType); } else{ pHalData->TRxAntDivType = registry_par->antdiv_type ;//GetRegAntDivType(pAdapter); } - - -/* - if(!AutoLoadFail) - { - // Antenna Diversity setting. - pHalData->AntDivCfg = (hwinfo[RF_OPTION1_8723A]&0x18)>>3; - - if(BT_1Ant(pAdapter)) - pHalData->AntDivCfg = 0; - pHalData->ReverseDPDT = (hwinfo[RF_OPTION1_8723A]&BIT5) >> 5; - } - else - { - pHalData->AntDivCfg = 0; - pHalData->ReverseDPDT = 1; - } - RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("EEPROM SWAS: bHwAntDiv = %x, TRxAntDivType = %x\n", - pHalData->AntDivCfg, pHalData->TRxAntDivType)); -*/ -#endif + DBG_8192C("%s: AntDivCfg=%d, AntDivType=%d\n", + __FUNCTION__, pHalData->AntDivCfg, pHalData->TRxAntDivType); +#endif } VOID @@ -4652,30 +4673,6 @@ u8 SCMapping_8723B(PADAPTER Adapter, struct pkt_attrib *pattrib) return SCSettingOfDesc; } -#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) -void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc) -{ - u16 *usPtr = (u16*)ptxdesc; - u32 count; - u32 index; - u16 checksum = 0; - - - // Clear first - ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); - - // checksume is always calculated by first 32 bytes, - // and it doesn't depend on TX DESC length. - // Thomas,Lucas@SD4,20130515 - count = 16; - - for (index = 0; index < count; index++) { - checksum ^= le16_to_cpu(*(usPtr + index)); - } - - ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff); -} -#endif static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib) { @@ -4807,7 +4804,8 @@ static void rtl8723b_fill_default_txdesc( SET_TX_DESC_AGG_ENABLE_8723B(pbuf, 1); SET_TX_DESC_MAX_AGG_NUM_8723B(pbuf, 0x1F); SET_TX_DESC_AMPDU_DENSITY_8723B(pbuf, pattrib->ampdu_spacing); - } else { + } + else { SET_TX_DESC_AGG_BREAK_8723B(pbuf, 1); } @@ -4832,7 +4830,9 @@ static void rtl8723b_fill_default_txdesc( SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1); } SET_TX_DESC_TX_RATE_8723B(pbuf, padapter->fix_rate & 0x7F); - SET_TX_DESC_DISABLE_FB_8723B(pbuf, 1); + if (!padapter->data_fb) { + SET_TX_DESC_DISABLE_FB_8723B(pbuf, 1); + } } if (pattrib->ldpc) { @@ -4942,10 +4942,7 @@ static void rtl8723b_fill_default_txdesc( #ifdef CONFIG_USB_HCI pkt_offset = pxmitframe->pkt_offset; offset += (pxmitframe->pkt_offset >> 3); - SET_TX_DESC_OFFSET_8723B(pbuf, TXDESC_SIZE + (pxmitframe->pkt_offset >> 3)); -#else // CONFIG_SDIO_HCI & CONFIG_GSPI_HCI - offset += OFFSET_SZ; -#endif // !CONFIG_USB_HCI +#endif // CONFIG_USB_HCI #ifdef CONFIG_TX_EARLY_MODE if (pxmitframe->frame_tag == DATA_FRAMETAG) { @@ -4986,6 +4983,10 @@ void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf) { rtl8723b_fill_default_txdesc(pxmitframe, pbuf); +#ifdef CONFIG_ANTENNA_DIVERSITY + ODM_SetTxAntByTxInfo(&GET_HAL_DATA(padapter)->odmpriv, pbuf, pxmitframe->attrib.mac_id); +#endif // CONFIG_ANTENNA_DIVERSITY + #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) rtl8723b_cal_txdesc_chksum((struct tx_desc*)pbuf); #endif @@ -5878,24 +5879,66 @@ void CCX_FwC2HTxRpt_8723b(PADAPTER padapter, u8 *pdata, u8 len) } #ifdef CONFIG_FW_C2H_DEBUG +/* + * C2H RX package original is 128. + * If enable CONFIG_FW_C2H_DEBUG, it should increase to 256. + * C2H FW debug message: + * without aggregate: + * {C2H CmdID, Seq, SubID, Len, Content[0~n]} + * Content[0~n] = { 'a' , 'b' , 'c' ,..., 'z' , '\n'} + * + * with aggregate: + * {C2H CmdID, Seq, SubID, Len, Content[0~n]} + * Content[0~n] = { 'a' , 'b' , 'c' ,..., 'z', '\n' , Extend C2H pkt 2...} + * Extend C2H pkt 2 = {C2H CmdID, Seq, SubID, Len, Content = { 'a' , 'b' , 'c' ,..., 'z' , '\n'}} + * + * Author: Isaac + */ void Debug_FwC2H_8723b(PADAPTER padapter, u8 *pdata, u8 len) { - u8 data_len = *(pdata + 1); - u8 seq_no = *(pdata + 2); int i = 0; - int cnt = 0; + int cnt = 0, total_length = 0; u8 buf[128]={0}; + u8 more_data = _FALSE; + u8 *nextdata = NULL; + u8 test = 0; - //DBG_871X("%s: SubID: %02x, data_len: %02x, Content: %02x\n", - // __func__, *pdata, *(pdata+1), *(pdata+2)); + u8 data_len; + u8 seq_no; + + nextdata = pdata; +#if 0 + for (i = 0 ; i < len ; i++) { + printk("%02x ", pdata[i]); + if ((i + 1)%8 == 0) + printk("\n"); + } + printk("\n"); +#endif + do { + data_len = *(nextdata + 1); + seq_no = *(nextdata + 2); - for (i = 0 ; i < data_len ; i++) - cnt += sprintf((buf+cnt), "%c", pdata[3 + i]); + for (i = 0 ; i < data_len - 2 ; i++) { + cnt += sprintf((buf+cnt), "%c", nextdata[3 + i]); + + if (nextdata[3 + i] == 0x0a && nextdata[4 + i] == 0xff) { + more_data = _TRUE; + } else if (nextdata[3 + i] == 0x0a && nextdata[4 + i] != 0xff) { + more_data = _FALSE; + } + } - if (seq_no == 0) - DBG_871X("[RTKFW, SEQ=%d]: %s\n", seq_no, buf); - else DBG_871X("[RTKFW, SEQ=%d]: %s", seq_no, buf); + data_len += 3; + total_length += data_len; + + if (more_data == _TRUE) { + _rtw_memset(buf, '\0', 128); + cnt = 0; + nextdata = (pdata + total_length); + } + } while (more_data == _TRUE); } #endif //CONFIG_FW_C2H_DEBUG @@ -6053,7 +6096,7 @@ static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2h break; case C2H_CCX_TX_RPT: -// CCX_FwC2HTxRpt(padapter, QueueID, tmpBuf); + CCX_FwC2HTxRpt_8723b(padapter, c2hBuf, pC2hEvent->CmdLen); break; #ifdef CONFIG_BT_COEXIST @@ -6088,6 +6131,13 @@ static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2h MPTBT_FwC2hBtMpCtrl(padapter, c2hBuf, pC2hEvent->CmdLen); break; #endif + +#ifdef CONFIG_FW_C2H_DEBUG + case C2H_8723B_FW_DEBUG: + Debug_FwC2H_8723b(padapter, c2hBuf, pC2hEvent->CmdLen); + break; +#endif // CONFIG_FW_C2H_DEBUG + default: break; } @@ -6102,7 +6152,7 @@ static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2h #ifdef CONFIG_C2H_PACKET_EN -void C2HPacketHandler_8723B(PADAPTER padapter, u8 *pbuffer, u16 length) +static void C2HPacketHandler_8723B(PADAPTER padapter, u8 *pbuffer, u16 length) { C2H_EVT_HDR C2hEvent; u8 *tmpBuf=NULL; @@ -6117,18 +6167,55 @@ void C2HPacketHandler_8723B(PADAPTER padapter, u8 *pbuffer, u16 length) #endif C2hEvent.CmdID = pbuffer[0]; C2hEvent.CmdSeq = pbuffer[1]; - C2hEvent.CmdLen = length -2; - tmpBuf = pbuffer+2; + C2hEvent.CmdLen = length - 2; + tmpBuf = pbuffer + 2; //DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n", // __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq); RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HPacketHandler_8723B(): Command Content:\n", tmpBuf, C2hEvent.CmdLen); - process_c2h_event(padapter,&C2hEvent, tmpBuf); + process_c2h_event(padapter, &C2hEvent, tmpBuf); //c2h_handler_8723b(padapter,&C2hEvent); return; } -#else + +void rtl8723b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length) +{ + C2H_EVT_HDR C2hEvent; + u8 *pdata; + + + if (length == 0) + return; + + C2hEvent.CmdID = pbuf[0]; + C2hEvent.CmdSeq = pbuf[1]; + C2hEvent.CmdLen = length - 2; + pdata = pbuf + 2; + + DBG_8192C("%s: C2H, ID=%d seq=%d len=%d\n", + __FUNCTION__, C2hEvent.CmdID, C2hEvent.CmdSeq, C2hEvent.CmdLen); + + switch (C2hEvent.CmdID) { + case C2H_CCX_TX_RPT: +#ifdef CONFIG_FW_C2H_DEBUG + case C2H_8723B_FW_DEBUG: +#endif // CONFIG_FW_C2H_DEBUG + process_c2h_event(padapter, &C2hEvent, pdata); + break; + + default: + pdata = rtw_zmalloc(length); + if (pdata == NULL) + break; + _rtw_memcpy(pdata, pbuf, length); + if (rtw_c2h_packet_wk_cmd(padapter, pdata, length) == _FAIL) + rtw_mfree(pdata, length); + break; + } +} + +#else // !CONFIG_C2H_PACKET_EN // //C2H event format: // Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID @@ -6191,7 +6278,7 @@ static void C2HCommandHandler(PADAPTER padapter) c2h_handler_8723b(padapter,&C2hEvent); if (tmpBuf) rtw_mfree(tmpBuf, C2hEvent.CmdLen); -#endif +#endif // CONFIG_SDIO_HCI || CONFIG_GSPI_HCI #ifdef CONFIG_USB_HCI HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter); @@ -6202,7 +6289,8 @@ static void C2HCommandHandler(PADAPTER padapter) C2hEvent.CmdSeq =pHalData->C2hArray[USB_C2H_SEQ_OFFSET]; c2h_handler_8723b(padapter,(u8 *)&C2hEvent); //process_c2h_event(padapter,&C2hEvent,&pHalData->C2hArray[USB_C2H_EVENT_OFFSET]); -#endif +#endif // CONFIG_USB_HCI + //REG_C2HEVT_CLEAR have done in process_c2h_event return; exit: @@ -6210,7 +6298,7 @@ exit: return; } -#endif +#endif // !CONFIG_C2H_PACKET_EN void SetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val) { @@ -6567,20 +6655,6 @@ _func_enter_; rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|(RCR_CBSSID_DATA)); break; #endif //CONFIG_TDLS - case HW_VAR_INITIAL_GAIN: - { - DIG_T *pDigTable = &pHalData->odmpriv.DM_DigTable; - u32 rx_gain = *(u32*)val; - - if (rx_gain == 0xff) {//restore rx gain - ODM_Write_DIG(&pHalData->odmpriv, pDigTable->BackupIGValue); - } else { - pDigTable->BackupIGValue = pDigTable->CurIGValue; - ODM_Write_DIG(&pHalData->odmpriv, rx_gain); - } - } - break; - #ifdef CONFIG_SW_ANTENNA_DIVERSITY case HW_VAR_ANTENNA_DIVERSITY_LINK: //SwAntDivRestAfterLink8192C(padapter); @@ -6720,16 +6794,13 @@ _func_enter_; rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper); } break; - + #ifndef CONFIG_C2H_PACKET_EN case HW_VAR_C2H_HANDLE: - C2HCommandHandler(padapter); - break; + C2HCommandHandler(padapter); + break; #endif -// case HW_VAR_C2H_HANDLE: -// C2HCommandHandler(padapter); -// break; case HW_VAR_H2C_MEDIA_STATUS_RPT: { u16 mstatus_rpt = (*(u16 *)val); @@ -6795,41 +6866,73 @@ _func_enter_; break; case HW_VAR_MACID_SLEEP: - // Input is MACID - val32 = *(u32*)val; - if (val32 > 31) { - DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] Invalid macid(%d)\n", - FUNC_ADPT_ARG(padapter), val32); + { + u32 reg_macid_sleep; + u8 bit_shift; + u8 id = *(u8*)val; + + if (id < 32) { + reg_macid_sleep = REG_MACID_SLEEP; + bit_shift = id; + } else if (id < 64) { + reg_macid_sleep = REG_MACID_SLEEP_1; + bit_shift = id-32; + } else if (id < 96) { + reg_macid_sleep = REG_MACID_SLEEP_2; + bit_shift = id-64; + } else if (id < 128) { + reg_macid_sleep = REG_MACID_SLEEP_3; + bit_shift = id-96; + } else { + rtw_warn_on(1); break; } - val8 = (u8)val32; // macid is between 0~31 - val32 = rtw_read32(padapter, REG_MACID_SLEEP); - DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org MACID_SLEEP=0x%08X\n", - FUNC_ADPT_ARG(padapter), val8, val32); - if (val32 & BIT(val8)) + val32 = rtw_read32(padapter, reg_macid_sleep); + DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n", + FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32); + + if (val32 & BIT(bit_shift)) break; - val32 |= BIT(val8); - rtw_write32(padapter, REG_MACID_SLEEP, val32); + + val32 |= BIT(bit_shift); + rtw_write32(padapter, reg_macid_sleep, val32); + } break; case HW_VAR_MACID_WAKEUP: - // Input is MACID - val32 = *(u32*)val; - if (val32 > 31) { - DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] Invalid macid(%d)\n", - FUNC_ADPT_ARG(padapter), val32); + { + u32 reg_macid_sleep; + u8 bit_shift; + u8 id = *(u8*)val; + + if (id < 32) { + reg_macid_sleep = REG_MACID_SLEEP; + bit_shift = id; + } else if (id < 64) { + reg_macid_sleep = REG_MACID_SLEEP_1; + bit_shift = id-32; + } else if (id < 96) { + reg_macid_sleep = REG_MACID_SLEEP_2; + bit_shift = id-64; + } else if (id < 128) { + reg_macid_sleep = REG_MACID_SLEEP_3; + bit_shift = id-96; + } else { + rtw_warn_on(1); break; } - val8 = (u8)val32; // macid is between 0~31 - val32 = rtw_read32(padapter, REG_MACID_SLEEP); - DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org MACID_SLEEP=0x%08X\n", - FUNC_ADPT_ARG(padapter), val8, val32); - if (!(val32 & BIT(val8))) + val32 = rtw_read32(padapter, reg_macid_sleep); + DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n", + FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32); + + if (!(val32 & BIT(bit_shift))) break; - val32 &= ~BIT(val8); - rtw_write32(padapter, REG_MACID_SLEEP, val32); + + val32 &= ~BIT(bit_shift); + rtw_write32(padapter, reg_macid_sleep, val32); + } break; default: @@ -6840,6 +6943,74 @@ _func_enter_; _func_exit_; } +struct qinfo_8723b { + u32 head:8; + u32 pkt_num:7; + u32 tail:8; + u32 ac:2; + u32 macid:7; +}; + +struct bcn_qinfo_8723b { + u16 head:8; + u16 pkt_num:8; +}; + +void dump_qinfo_8723b(void *sel, struct qinfo_8723b *info, const char *tag) +{ + //if (info->pkt_num) + DBG_871X_SEL_NL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n" + , tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac + ); +} + +void dump_bcn_qinfo_8723b(void *sel, struct bcn_qinfo_8723b *info, const char *tag) +{ + //if (info->pkt_num) + DBG_871X_SEL_NL(sel, "%shead:0x%02x, pkt_num:%u\n" + , tag ? tag : "", info->head, info->pkt_num + ); +} + +void dump_mac_qinfo_8723b(void *sel, _adapter *adapter) +{ + u32 q0_info; + u32 q1_info; + u32 q2_info; + u32 q3_info; + u32 q4_info; + u32 q5_info; + u32 q6_info; + u32 q7_info; + u32 mg_q_info; + u32 hi_q_info; + u16 bcn_q_info; + + q0_info = rtw_read32(adapter, REG_Q0_INFO); + q1_info = rtw_read32(adapter, REG_Q1_INFO); + q2_info = rtw_read32(adapter, REG_Q2_INFO); + q3_info = rtw_read32(adapter, REG_Q3_INFO); + q4_info = rtw_read32(adapter, REG_Q4_INFO); + q5_info = rtw_read32(adapter, REG_Q5_INFO); + q6_info = rtw_read32(adapter, REG_Q6_INFO); + q7_info = rtw_read32(adapter, REG_Q7_INFO); + mg_q_info = rtw_read32(adapter, REG_MGQ_INFO); + hi_q_info = rtw_read32(adapter, REG_HGQ_INFO); + bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO); + + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q0_info, "Q0 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q1_info, "Q1 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q2_info, "Q2 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q3_info, "Q3 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q4_info, "Q4 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q5_info, "Q5 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q6_info, "Q6 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q7_info, "Q7 "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&mg_q_info, "MG "); + dump_qinfo_8723b(sel, (struct qinfo_8723b *)&hi_q_info, "HI "); + dump_bcn_qinfo_8723b(sel, (struct bcn_qinfo_8723b *)&bcn_q_info, "BCN "); +} + void GetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val) { PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); @@ -6942,6 +7113,9 @@ void GetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val) *val = rtw_read8(padapter, REG_SYS_CLKR); break; #endif + case HW_VAR_DUMP_MAC_QUEUE_INFO: + dump_mac_qinfo_8723b(val, padapter); + break; default: GetHwReg(padapter, variable, val); break; @@ -6971,6 +7145,27 @@ u8 SetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval) return bResult; } +#ifdef CONFIG_C2H_PACKET_EN +void SetHwRegWithBuf8723B(PADAPTER padapter, u8 variable, u8 *pbuf, int len) +{ + PHAL_DATA_TYPE pHalData; + +_func_enter_; + + pHalData = GET_HAL_DATA(padapter); + + switch (variable) { + case HW_VAR_C2H_HANDLE: + C2HPacketHandler_8723B(padapter, pbuf, len); + break; + + default: + break; + } +_func_exit_; +} +#endif // CONFIG_C2H_PACKET_EN + /* * Description: * Query setting of specified variable. @@ -7080,7 +7275,9 @@ u8 GetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval) case HAL_DEF_MACID_SLEEP: *(u8*)pval = _TRUE; // support macid sleep break; - + case HAL_DEF_TX_PAGE_SIZE: + *(( u32*)pval) = PAGE_SIZE_128; + break; default: bResult = GetHalDefVar(padapter, variable, pval); break; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_phycfg.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_phycfg.c index a36620583a5d..137270e00dad 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_phycfg.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_phycfg.c @@ -498,6 +498,10 @@ s32 PHY_MACConfig8723B(PADAPTER Adapter) #endif//CONFIG_EMBEDDED_FWIMG } +#ifdef CONFIG_GPIO_WAKEUP + rtw_clear_hostwakeupgpio(Adapter); +#endif // CONFIG_GPIO_WAKEUP + return rtStatus; } @@ -794,10 +798,14 @@ PHY_BBConfig8723B( RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN); rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1)); + // switch ant to BT #ifdef CONFIG_USB_HCI rtw_write32(Adapter, 0x948, 0x0); // USB use Antenna S0 #else - rtw_write32(Adapter, 0x948, 0x280); // Others use Antenna S1 + if (pHalData->ant_path == ODM_RF_PATH_A) + rtw_write32(Adapter, 0x948, 0x280); + else + rtw_write32(Adapter, 0x948, 0x0); #endif rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_rxdesc.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_rxdesc.c index 6962cb6b265d..eedc8c20b4f9 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_rxdesc.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_rxdesc.c @@ -138,8 +138,7 @@ static void process_link_qual(_adapter *padapter,union recv_frame *prframe) }// Process_UiLinkQuality8192S - -void rtl8723b_process_phy_info(_adapter *padapter, void *prframe) +static void process_phy_info(_adapter *padapter, void *prframe) { union recv_frame *precvframe = (union recv_frame *)prframe; // @@ -162,44 +161,121 @@ void rtl8723b_process_phy_info(_adapter *padapter, void *prframe) } -void rtl8723b_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc) +/* + * Notice: + * Before calling this function, + * precvframe->u.hdr.rx_data should be ready! + */ +void rtl8723b_query_rx_phy_status(union recv_frame *precvframe, struct phy_stat *pphy_status) { - struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + PADAPTER padapter = precvframe->u.hdr.adapter; + struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PODM_PHY_INFO_T pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); - _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); + u8 *wlanhdr; + ODM_PACKET_INFO_T pkt_info; + u8 *sa = NULL; + //_irqL irqL; + struct sta_priv *pstapriv; + struct sta_info *psta; - //Offset 0 - pattrib->pkt_len = (u16)GET_RX_STATUS_DESC_PKT_LEN_8723B(pdesc);//(le32_to_cpu(pdesc->rxdw0)&0x00003fff) - pattrib->crc_err = (u8)GET_RX_STATUS_DESC_CRC32_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw0) >> 14) & 0x1); - pattrib->icv_err = (u8)GET_RX_STATUS_DESC_ICV_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw0) >> 15) & 0x1); - pattrib->drvinfo_sz = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE_8723B(pdesc) * 8;//((le32_to_cpu(pdesc->rxdw0) >> 16) & 0xf) * 8;//uint 2^3 = 8 bytes - pattrib->encrypt = (u8)GET_RX_STATUS_DESC_SECURITY_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw0) >> 20) & 0x7); - pattrib->qos = (u8)GET_RX_STATUS_DESC_QOS_8723B(pdesc);//(( le32_to_cpu( pdesc->rxdw0 ) >> 23) & 0x1);// Qos data, wireless lan header length is 26 - pattrib->shift_sz = (u8)GET_RX_STATUS_DESC_SHIFT_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw0) >> 24) & 0x3); - pattrib->physt = (u8)GET_RX_STATUS_DESC_PHY_STATUS_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw0) >> 26) & 0x1); - pattrib->bdecrypted = !GET_RX_STATUS_DESC_SWDEC_8723B(pdesc);//(le32_to_cpu(pdesc->rxdw0) & BIT(27))? 0:1; - - //Offset 4 - pattrib->priority = (u8)GET_RX_STATUS_DESC_TID_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw1) >> 8) & 0xf); - pattrib->mdata = (u8)GET_RX_STATUS_DESC_MORE_DATA_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw1) >> 26) & 0x1); - pattrib->mfrag = (u8)GET_RX_STATUS_DESC_MORE_FRAG_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw1) >> 27) & 0x1);//more fragment bit - - //Offset 8 - pattrib->seq_num = (u16)GET_RX_STATUS_DESC_SEQ_8723B(pdesc);//(le32_to_cpu(pdesc->rxdw2) & 0x00000fff); - pattrib->frag_num = (u8)GET_RX_STATUS_DESC_FRAG_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw2) >> 12) & 0xf);//fragmentation number - - if (GET_RX_STATUS_DESC_RPT_SEL_8723B(pdesc)) - pattrib->pkt_rpt_type = C2H_PACKET; - else - pattrib->pkt_rpt_type = NORMAL_RX; - //Offset 12 - pattrib->data_rate=(u8)GET_RX_STATUS_DESC_RX_RATE_8723B(pdesc);//((le32_to_cpu(pdesc->rxdw3))&0x7f); + pkt_info.bPacketMatchBSSID =_FALSE; + pkt_info.bPacketToSelf = _FALSE; + pkt_info.bPacketBeacon = _FALSE; + + wlanhdr = get_recvframe_data(precvframe); + + pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && + !pattrib->icv_err && !pattrib->crc_err && + _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); - //Offset 16 - //Offset 20 + pkt_info.bToSelf = ((!pattrib->icv_err) && (!pattrib->crc_err)) && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); + pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); + + pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON); +/* + if(pkt_info.bPacketBeacon){ + if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){ + sa = padapter->mlmepriv.cur_network.network.MacAddress; + #if 0 + { + DBG_871X("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n", + sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]); + } + #endif + } + //to do Ad-hoc + } + else{ + sa = get_sa(wlanhdr); + } +*/ + sa = get_ta(wlanhdr); + + pkt_info.StationID = 0xFF; + + pstapriv = &padapter->stapriv; + psta = rtw_get_stainfo(pstapriv, sa); + if (psta) + pkt_info.StationID = psta->mac_id; + pkt_info.DataRate = pattrib->data_rate; + + ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8*)pphy_status, &pkt_info); + if(psta) + psta->rssi = pattrib->phy_info.RecvSignalPower; + + precvframe->u.hdr.psta = NULL; + if (pkt_info.bPacketMatchBSSID && + (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)) { + if (psta) { + precvframe->u.hdr.psta = psta; + process_phy_info(padapter, precvframe); + } + } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { + if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) + if (psta) + precvframe->u.hdr.psta = psta; + process_phy_info(padapter, precvframe); + } } +void rtl8723b_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc) +{ + struct rx_pkt_attrib *pattrib; + + + pattrib = &precvframe->u.hdr.attrib; + _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); + pattrib->pkt_len = (u16)GET_RX_STATUS_DESC_PKT_LEN_8723B(pdesc); + pattrib->pkt_rpt_type = GET_RX_STATUS_DESC_RPT_SEL_8723B(pdesc) ? C2H_PACKET : NORMAL_RX; + + if (pattrib->pkt_rpt_type == NORMAL_RX) { + // Offset 0 + pattrib->crc_err = (u8)GET_RX_STATUS_DESC_CRC32_8723B(pdesc); + pattrib->icv_err = (u8)GET_RX_STATUS_DESC_ICV_8723B(pdesc); + pattrib->drvinfo_sz = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE_8723B(pdesc) << 3; + pattrib->encrypt = (u8)GET_RX_STATUS_DESC_SECURITY_8723B(pdesc); + pattrib->qos = (u8)GET_RX_STATUS_DESC_QOS_8723B(pdesc); + pattrib->shift_sz = (u8)GET_RX_STATUS_DESC_SHIFT_8723B(pdesc); + pattrib->physt = (u8)GET_RX_STATUS_DESC_PHY_STATUS_8723B(pdesc); + pattrib->bdecrypted = (u8)GET_RX_STATUS_DESC_SWDEC_8723B(pdesc) ? 0 : 1; + + // Offset 4 + pattrib->priority = (u8)GET_RX_STATUS_DESC_TID_8723B(pdesc); + pattrib->amsdu = (u8)GET_RX_STATUS_DESC_AMSDU_8723B(pdesc); + pattrib->mdata = (u8)GET_RX_STATUS_DESC_MORE_DATA_8723B(pdesc); + pattrib->mfrag = (u8)GET_RX_STATUS_DESC_MORE_FRAG_8723B(pdesc); + + // Offset 8 + pattrib->seq_num = (u16)GET_RX_STATUS_DESC_SEQ_8723B(pdesc); + pattrib->frag_num = (u8)GET_RX_STATUS_DESC_FRAG_8723B(pdesc); + + // Offset 12 + pattrib->data_rate = (u8)GET_RX_STATUS_DESC_RX_RATE_8723B(pdesc); + } +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_recv.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_recv.c index 4c960638c45f..c0e893db6792 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_recv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_recv.c @@ -21,24 +21,6 @@ #include - -void rtl8723bu_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf) -{ - - precvbuf->transfer_len = 0; - - precvbuf->len = 0; - - precvbuf->ref_cnt = 0; - - if(precvbuf->pbuf) - { - precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pbuf; - precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ; - } - -} - int rtl8723bu_init_recv_priv(_adapter *padapter) { struct recv_priv *precvpriv = &padapter->recvpriv; @@ -52,7 +34,7 @@ int rtl8723bu_init_recv_priv(_adapter *padapter) #ifdef PLATFORM_LINUX tasklet_init(&precvpriv->recv_tasklet, - (void(*)(unsigned long))rtl8723bu_recv_tasklet, + (void(*)(unsigned long))usb_recv_tasklet, (unsigned long)padapter); #endif @@ -226,142 +208,5 @@ void rtl8723bu_free_recv_priv (_adapter *padapter) #endif #endif - -} - - -void update_recvframe_attrib( - PADAPTER padapter, - union recv_frame *precvframe, - u8 *prxstat) -{ - struct rx_pkt_attrib *pattrib; - - - pattrib = &precvframe->u.hdr.attrib; - _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); - - // update rx report to recv_frame attribute - pattrib->pkt_len = (u16)GET_RX_STATUS_DESC_PKT_LEN_8723B(prxstat); - pattrib->pkt_rpt_type = GET_RX_STATUS_DESC_RPT_SEL_8723B(prxstat) ? C2H_PACKET : NORMAL_RX; - - if (pattrib->pkt_rpt_type == NORMAL_RX) { - // Normal rx packet - pattrib->drvinfo_sz = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE_8723B(prxstat) << 3; - pattrib->shift_sz = (u8)GET_RX_STATUS_DESC_SHIFT_8723B(prxstat); - pattrib->physt = (u8)GET_RX_STATUS_DESC_PHY_STATUS_8723B(prxstat); - - pattrib->crc_err = (u8)GET_RX_STATUS_DESC_CRC32_8723B(prxstat); - pattrib->icv_err = (u8)GET_RX_STATUS_DESC_ICV_8723B(prxstat); - - pattrib->bdecrypted = (u8)GET_RX_STATUS_DESC_SWDEC_8723B(prxstat) ? 0 : 1; - pattrib->encrypt = (u8)GET_RX_STATUS_DESC_SECURITY_8723B(prxstat); - - pattrib->qos = (u8)GET_RX_STATUS_DESC_QOS_8723B(prxstat); - pattrib->priority = (u8)GET_RX_STATUS_DESC_TID_8723B(prxstat); - - pattrib->amsdu = (u8)GET_RX_STATUS_DESC_AMSDU_8723B(prxstat); - - pattrib->seq_num = (u16)GET_RX_STATUS_DESC_SEQ_8723B(prxstat); - pattrib->frag_num = (u8)GET_RX_STATUS_DESC_FRAG_8723B(prxstat); - pattrib->mfrag = (u8)GET_RX_STATUS_DESC_MORE_FRAG_8723B(prxstat); - pattrib->mdata = (u8)GET_RX_STATUS_DESC_MORE_DATA_8723B(prxstat); - - pattrib->data_rate = (u8)GET_RX_STATUS_DESC_RX_RATE_8723B(prxstat); - } -} - -/* - * Notice: - * Before calling this function, - * precvframe->u.hdr.rx_data should be ready! - */ -void update_recvframe_phyinfo( - union recv_frame *precvframe, - struct phy_stat *pphy_status) -{ - PADAPTER padapter = precvframe->u.hdr.adapter; - struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; - HAL_DATA_TYPE *pHalData= GET_HAL_DATA(padapter); - PODM_PHY_INFO_T pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); - - u8 *wlanhdr; - ODM_PACKET_INFO_T pkt_info; - u8 *sa = NULL; - //_irqL irqL; - struct sta_priv *pstapriv; - struct sta_info *psta; - - pkt_info.bPacketMatchBSSID =_FALSE; - pkt_info.bPacketToSelf = _FALSE; - pkt_info.bPacketBeacon = _FALSE; - - - wlanhdr = get_recvframe_data(precvframe); - - pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && - !pattrib->icv_err && !pattrib->crc_err && - _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); - - pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); - - pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON); -/* - if(pkt_info.bPacketBeacon){ - if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){ - sa = padapter->mlmepriv.cur_network.network.MacAddress; - #if 0 - { - DBG_871X("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n", - sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]); - } - #endif - } - //to do Ad-hoc - } - else{ - sa = get_sa(wlanhdr); - } -*/ - sa = get_ta(wlanhdr); - - pkt_info.StationID = 0xFF; - - pstapriv = &padapter->stapriv; - psta = rtw_get_stainfo(pstapriv, sa); - if (psta) - { - pkt_info.StationID = psta->mac_id; - //DBG_871X("%s ==> StationID(%d)\n",__FUNCTION__,pkt_info.StationID); - } - pkt_info.DataRate = pattrib->data_rate; - - //rtl8723b_query_rx_phy_status(precvframe, pphy_status); - //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); - ODM_PhyStatusQuery(&pHalData->odmpriv,pPHYInfo,(u8 *)pphy_status,&(pkt_info)); - if(psta) psta->rssi = pattrib->phy_info.RecvSignalPower; - //_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); - precvframe->u.hdr.psta = NULL; - if (pkt_info.bPacketMatchBSSID && - (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)) - { - if (psta) - { - precvframe->u.hdr.psta = psta; - rtl8723b_process_phy_info(padapter, precvframe); - } - } - else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) - { - if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) - { - if (psta) - { - precvframe->u.hdr.psta = psta; - } - } - rtl8723b_process_phy_info(padapter, precvframe); - } } - diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_xmit.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_xmit.c index 176e8809e15c..0540a38f0109 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_xmit.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/rtl8723bu_xmit.c @@ -524,6 +524,9 @@ s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); xmitframe_plist = get_next(xmitframe_plist); + if(_FAIL == rtw_hal_busagg_qsel_check(padapter,pfirstframe->attrib.qsel,pxmitframe->attrib.qsel)) + break; + len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset if (pbuf + len > MAX_XMITBUF_SZ) break; @@ -745,7 +748,6 @@ static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe) //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); #endif - _enter_critical_bh(&pxmitpriv->lock, &irqL); if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_halinit.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_halinit.c index f6a0d8a7746a..a837014d5b00 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_halinit.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_halinit.c @@ -21,6 +21,9 @@ #define _USB_HALINIT_C_ #include +#ifdef CONFIG_WOWLAN +#include "hal_com_h2c.h" +#endif @@ -180,6 +183,10 @@ static u8 _InitPowerOn_8723BU(PADAPTER padapter) //DBG_8192C("%s: REG_PAD_CTRL1(0x%x)=0x%02X\n", __FUNCTION__, REG_PAD_CTRL1_8723B, rtw_read8(padapter, REG_PAD_CTRL1_8723B)); #endif // CONFIG_BT_COEXIST +#ifdef CONFIG_GPIO_WAKEUP + rtw_clear_hostwakeupgpio(padapter); +#endif // CONFIG_GPIO_WAKEUP + return status; } @@ -253,38 +260,6 @@ static u8 _LLTRead( // MAC init functions // //--------------------------------------------------------------- -static VOID -_SetMacID( - IN PADAPTER Adapter, u8* MacID - ) -{ - u32 i; - for(i=0 ; i< MAC_ADDR_LEN ; i++){ -#ifdef CONFIG_CONCURRENT_MODE - if(Adapter->iface_type == IFACE_PORT1) - rtw_write32(Adapter, REG_MACID1+i, MacID[i]); - else -#endif - rtw_write32(Adapter, REG_MACID+i, MacID[i]); - } -} - -static VOID -_SetBSSID( - IN PADAPTER Adapter, u8* BSSID - ) -{ - u32 i; - for(i=0 ; i< MAC_ADDR_LEN ; i++){ -#ifdef CONFIG_CONCURRENT_MODE - if(Adapter->iface_type == IFACE_PORT1) - rtw_write32(Adapter, REG_BSSID1+i, BSSID[i]); - else -#endif - rtw_write32(Adapter, REG_BSSID+i, BSSID[i]); - } -} - // Shall USB interface init this? static VOID @@ -794,15 +769,8 @@ usb_AggSettingTxUpdate( * * Output/Return: NONE * - * Revised History: - * When Who Remark - * 12/10/2010 MHC Seperate to smaller function. - * *---------------------------------------------------------------------------*/ -static VOID -usb_AggSettingRxUpdate( - IN PADAPTER Adapter - ) +static void usb_AggSettingRxUpdate(PADAPTER padapter) { PHAL_DATA_TYPE pHalData; u8 aggctrl; @@ -810,12 +778,12 @@ usb_AggSettingRxUpdate( u32 agg_size; - pHalData = GET_HAL_DATA(Adapter); + pHalData = GET_HAL_DATA(padapter); - aggctrl = rtw_read8(Adapter, REG_TRXDMA_CTRL); + aggctrl = rtw_read8(padapter, REG_TRXDMA_CTRL); aggctrl &= ~RXDMA_AGG_EN; - aggrx = rtw_read32(Adapter, REG_RXDMA_AGG_PG_TH); + aggrx = rtw_read32(padapter, REG_RXDMA_AGG_PG_TH); aggrx &= ~BIT_USB_RXDMA_AGG_EN; aggrx &= ~0xFF0F; // reset agg size and timeout @@ -863,8 +831,8 @@ usb_AggSettingRxUpdate( } #endif // CONFIG_USB_RX_AGGREGATION - rtw_write8(Adapter, REG_TRXDMA_CTRL, aggctrl); - rtw_write32(Adapter, REG_RXDMA_AGG_PG_TH, aggrx); + rtw_write8(padapter, REG_TRXDMA_CTRL, aggctrl); + rtw_write32(padapter, REG_RXDMA_AGG_PG_TH, aggrx); } static VOID @@ -2720,7 +2688,7 @@ static int _ReadAdapterInfo8723BU(PADAPTER Adapter) { //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); u32 start=rtw_get_current_time(); - + MSG_8192C("====> _ReadAdapterInfo8723BU\n"); //Efuse_InitSomeVar(Adapter); @@ -2826,26 +2794,7 @@ _func_enter_; _func_exit_; } -#ifdef CONFIG_C2H_PACKET_EN -void SetHwRegWithBuf8723B(PADAPTER padapter, u8 variable, u8 *pbuf, int len) -{ - PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); - -_func_enter_; - - switch (variable) - { - case HW_VAR_C2H_HANDLE: - DBG_8192C("%s len=%d \n",__func__,len); - C2HPacketHandler_8723B(padapter, pbuf, len); - break; - default: - break; - } -_func_exit_; -} -#endif // // Description: // Query setting of specified variable. @@ -2966,6 +2915,8 @@ void rtl8723bu_set_hal_ops(_adapter * padapter) _func_enter_; + rtl8723b_set_hal_ops(pHalFunc); + pHalFunc->hal_init = &rtl8723bu_hal_init; pHalFunc->hal_deinit = &rtl8723bu_hal_deinit; @@ -2997,9 +2948,7 @@ _func_enter_; pHalFunc->hal_xmit = &rtl8723bu_hal_xmit; pHalFunc->mgnt_xmit = &rtl8723bu_mgnt_xmit; pHalFunc->hal_xmitframe_enqueue = &rtl8723bu_hal_xmitframe_enqueue; -#ifdef CONFIG_C2H_PACKET_EN - pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8723B; -#endif + #ifdef CONFIG_HOSTAPD_MLME pHalFunc->hostap_mgnt_xmit_entry = &rtl8723bu_hostap_mgnt_xmit_entry; #endif @@ -3008,9 +2957,7 @@ _func_enter_; #ifdef CONFIG_XMIT_THREAD_MODE pHalFunc->xmit_thread_handler = &rtl8723bu_xmit_buf_handler; #endif - rtl8723b_set_hal_ops(pHalFunc); _func_exit_; - } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_ops.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_ops.c index 70948f1347b8..c5dc2682116f 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_ops.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/usb/usb_ops.c @@ -20,200 +20,6 @@ #include -static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - u8 data=0; - - _func_enter_; - - request = 0x05; - requesttype = 0x01;//read_in - index = 0;//n/a - - wvalue = (u16)(addr&0x0000ffff); - len = 1; - - usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); - - _func_exit_; - - return data; - -} - -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - u16 data=0; - - _func_enter_; - - request = 0x05; - requesttype = 0x01;//read_in - index = 0;//n/a - - wvalue = (u16)(addr&0x0000ffff); - len = 2; - - usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); - - _func_exit_; - - return data; - -} - -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - u32 data=0; - - _func_enter_; - - request = 0x05; - requesttype = 0x01;//read_in - index = 0;//n/a - - wvalue = (u16)(addr&0x0000ffff); - len = 4; - - usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); - - _func_exit_; - - return data; - -} - -static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - u8 data; - int ret; - - _func_enter_; - - request = 0x05; - requesttype = 0x00;//write_out - index = 0;//n/a - - wvalue = (u16)(addr&0x0000ffff); - len = 1; - - data = val; - - ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); - - _func_exit_; - - return ret; - -} - -static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - u16 data; - int ret; - - _func_enter_; - - request = 0x05; - requesttype = 0x00;//write_out - index = 0;//n/a - - wvalue = (u16)(addr&0x0000ffff); - len = 2; - - data = val; - - ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); - - _func_exit_; - - return ret; - -} - -static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - u32 data; - int ret; - - _func_enter_; - - request = 0x05; - requesttype = 0x00;//write_out - index = 0;//n/a - - wvalue = (u16)(addr&0x0000ffff); - len = 4; - data = val; - - - ret =usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); - - _func_exit_; - - return ret; - -} - -static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - u8 buf[VENDOR_CMD_MAX_DATA_LEN]={0}; - int ret; - - _func_enter_; - - request = 0x05; - requesttype = 0x00;//write_out - index = 0;//n/a - - wvalue = (u16)(addr&0x0000ffff); - len = length; - _rtw_memcpy(buf, pdata, len ); - - ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, buf, len, requesttype); - - _func_exit_; - - return ret; - -} - - #ifdef CONFIG_SUPPORT_USB_INT void interrupt_handler_8723bu(_adapter *padapter,u16 pkt_len,u8 *pbuf) { @@ -507,7 +313,7 @@ static s32 pre_recv_entry(union recv_frame *precvframe, struct phy_stat *pphy_st recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN); if (pattrib->physt) - update_recvframe_phyinfo(precvframe_if2, pphy_status); + rtl8723b_query_rx_phy_status(precvframe_if2, pphy_status); if(rtw_recv_entry(precvframe_if2) != _SUCCESS) { @@ -517,7 +323,7 @@ static s32 pre_recv_entry(union recv_frame *precvframe, struct phy_stat *pphy_st } //if (precvframe->u.hdr.attrib.physt) - // update_recvframe_phyinfo(precvframe, pphy_status); + // rtl8723b_query_rx_phy_status(precvframe, pphy_status); //ret = rtw_recv_entry(precvframe); #endif @@ -686,166 +492,117 @@ static s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status) } #endif -#ifdef CONFIG_C2H_PACKET_EN -static void rtl8723bu_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length) -{ - u8 *tmpBuf=NULL; - - if(length == 0) - return; - - DBG_871X("+%s() length=%d\n", __func__, length); - - tmpBuf = rtw_zmalloc(length); - if (tmpBuf == NULL) - return; - - _rtw_memcpy(tmpBuf, pbuf, length); - - rtw_c2h_packet_wk_cmd(padapter, tmpBuf, length); - - DBG_871X("-%s()\n", __func__); - - return; -} -#endif - -static int recvbuf2recvframe(_adapter *padapter, -#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX -struct recv_buf *precvbuf -#else -_pkt *pskb -#endif -) +int recvbuf2recvframe(PADAPTER padapter, void *ptr) { - u8 *pbuf; - u8 pkt_cnt = 0; - u32 pkt_offset; - s32 transfer_len; - u8 *pphy_status = NULL; - union recv_frame *precvframe = NULL; - struct rx_pkt_attrib *pattrib = NULL; - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - struct recv_priv *precvpriv = &padapter->recvpriv; - _queue *pfree_recv_queue = &precvpriv->free_recv_queue; + u8 *pbuf; + u8 pkt_cnt = 0; + u32 pkt_offset; + s32 transfer_len; + u8 *pdata, *pphy_status; + union recv_frame *precvframe = NULL; + struct rx_pkt_attrib *pattrib = NULL; + PHAL_DATA_TYPE pHalData; + struct recv_priv *precvpriv; + _queue *pfree_recv_queue; + _pkt *pskb; + + + pHalData = GET_HAL_DATA(padapter); + precvpriv = &padapter->recvpriv; + pfree_recv_queue = &precvpriv->free_recv_queue; #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX - transfer_len = (s32)precvbuf->transfer_len; - pbuf = precvbuf->pbuf; -#else - transfer_len = (s32)pskb->len; + pskb = NULL; + transfer_len = (s32)((struct recv_buf*)ptr)->transfer_len; + pbuf = ((struct recv_buf*)ptr)->pbuf; +#else // !CONFIG_USE_USB_BUFFER_ALLOC_RX + pskb = (_pkt*)ptr; + transfer_len = (s32)pskb->len; pbuf = pskb->data; -#endif//CONFIG_USE_USB_BUFFER_ALLOC_RX +#endif // !CONFIG_USE_USB_BUFFER_ALLOC_RX #ifdef CONFIG_USB_RX_AGGREGATION pkt_cnt = GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8723B(pbuf); #endif - do{ + do { precvframe = rtw_alloc_recvframe(pfree_recv_queue); - if(precvframe==NULL) - { - RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: precvframe==NULL\n")); - DBG_8192C("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __FUNCTION__, __LINE__); + if (precvframe == NULL) { + DBG_8192C("%s: rtw_alloc_recvframe() failed! RX Drop!\n", __FUNCTION__); goto _exit_recvbuf2recvframe; } - if(transfer_len >1500) - _rtw_init_listhead(&precvframe->u.hdr.list); + + if (transfer_len >1500) + _rtw_init_listhead(&precvframe->u.hdr.list); precvframe->u.hdr.precvbuf = NULL; //can't access the precvbuf for new arch. - precvframe->u.hdr.len=0; + precvframe->u.hdr.len = 0; - update_recvframe_attrib(padapter,precvframe, pbuf); + rtl8723b_query_rx_desc_status(precvframe, pbuf); pattrib = &precvframe->u.hdr.attrib; - - if ( (padapter->registrypriv.mp_mode == 0) && ((pattrib->crc_err) || (pattrib->icv_err))) - { - DBG_8192C("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err); + + if ((padapter->registrypriv.mp_mode == 0) + && ((pattrib->crc_err) || (pattrib->icv_err))) { + DBG_8192C("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", + __FUNCTION__, pattrib->crc_err, pattrib->icv_err); rtw_free_recvframe(precvframe, pfree_recv_queue); goto _exit_recvbuf2recvframe; - } + } pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len; - - if((pattrib->pkt_len<=0) || (pkt_offset>transfer_len)) - { - DBG_871X("%s()-%d: RX Warning! pkt_len=%d pkt_offset=%d transfer_len=%d\n", - __FUNCTION__, __LINE__, - pattrib->pkt_len, pkt_offset, transfer_len); + if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) { + DBG_8192C("%s: RX Error! pkt_len=%d pkt_offset=%d transfer_len=%d\n", + __FUNCTION__, pattrib->pkt_len, pkt_offset, transfer_len); rtw_free_recvframe(precvframe, pfree_recv_queue); goto _exit_recvbuf2recvframe; } - if(rtw_os_alloc_recvframe(padapter, precvframe, - (pbuf+pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), -#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX - NULL -#else - pskb -#endif - ) == _FAIL) - { - rtw_free_recvframe(precvframe, pfree_recv_queue); + pdata = pbuf + RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz; + if (rtw_os_alloc_recvframe(padapter, precvframe, pdata, pskb) == _FAIL) { + DBG_8192C("%s: RX Error! rtw_os_alloc_recvframe FAIL!\n", __FUNCTION__); + rtw_free_recvframe(precvframe, pfree_recv_queue); goto _exit_recvbuf2recvframe; - } + } recvframe_put(precvframe, pattrib->pkt_len); - //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); - if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet - { - if(pattrib->physt) - pphy_status = (pbuf + RXDESC_OFFSET); + if (pattrib->pkt_rpt_type == NORMAL_RX) { + if (pattrib->physt) + pphy_status = pbuf + RXDESC_OFFSET; + else + pphy_status = NULL; + #ifdef CONFIG_CONCURRENT_MODE - if(rtw_buddy_adapter_up(padapter)) - { - if(pre_recv_entry(precvframe, (struct phy_stat*)pphy_status) != _SUCCESS) - { - RT_TRACE(_module_rtl871x_recv_c_,_drv_err_, - ("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n")); + if (rtw_buddy_adapter_up(padapter)) { + if (pre_recv_entry(precvframe, (struct phy_stat*)pphy_status) != _SUCCESS) { + // Return fail except data frame + //DBG_8192C("%s: RX Error! (concurrent)pre_recv_entry FAIL!\n", __FUNCTION__); } } -#endif //CONFIG_CONCURRENT_MODE +#endif // CONFIG_CONCURRENT_MODE - if (pattrib->physt && pphy_status) - update_recvframe_phyinfo(precvframe, (struct phy_stat*)pphy_status); + if (pphy_status) + rtl8723b_query_rx_phy_status(precvframe, (struct phy_stat*)pphy_status); - if(rtw_recv_entry(precvframe) != _SUCCESS) { - RT_TRACE(_module_rtl871x_recv_c_,_drv_err_, - ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n")); + if (rtw_recv_entry(precvframe) != _SUCCESS) { + // Return fail except data frame + //DBG_8192C("%s: RX Error! rtw_recv_entry FAIL!\n", __FUNCTION__); } } - else{ // pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP,HIS_REPORT-USB HISR RTP - if (pattrib->pkt_rpt_type == C2H_PACKET) { - C2H_EVT_HDR C2hEvent; - - u16 len_c2h = pattrib->pkt_len; - u8 *pbuf_c2h = precvframe->u.hdr.rx_data; - u8 *pdata_c2h; - - C2hEvent.CmdID = pbuf_c2h[0]; - C2hEvent.CmdSeq = pbuf_c2h[1]; - C2hEvent.CmdLen = (len_c2h -2); - pdata_c2h = pbuf_c2h+2; - - DBG_8192C("rx C2H_PACKET, ID=%d, seq=%d, len=%d\n", - C2hEvent.CmdID, C2hEvent.CmdSeq, C2hEvent.CmdLen); - - if(C2hEvent.CmdID == C2H_CCX_TX_RPT) - { - CCX_FwC2HTxRpt_8723b(padapter, pdata_c2h, C2hEvent.CmdLen); - } - else - { + else { #ifdef CONFIG_C2H_PACKET_EN - rtl8723bu_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len); -#endif - } + if (pattrib->pkt_rpt_type == C2H_PACKET) { + rtl8723b_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len); + } + else { + DBG_8192C("%s: [WARNNING] RX type(%d) not be handled!\n", + __FUNCTION__, pattrib->pkt_rpt_type); } +#endif // CONFIG_C2H_PACKET_EN rtw_free_recvframe(precvframe, pfree_recv_queue); } @@ -853,12 +610,11 @@ _pkt *pskb // jaguar 8-byte alignment pkt_offset = (u16)_RND8(pkt_offset); pkt_cnt--; - pbuf += pkt_offset; + pbuf += pkt_offset; #endif transfer_len -= pkt_offset; precvframe = NULL; - - }while(transfer_len>0); + } while (transfer_len > 0); _exit_recvbuf2recvframe: @@ -866,440 +622,6 @@ _exit_recvbuf2recvframe: } -#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX -void rtl8723bu_recv_tasklet(void *priv) -{ - struct recv_buf *precvbuf = NULL; - _adapter *padapter = (_adapter*)priv; - struct recv_priv *precvpriv = &padapter->recvpriv; - - while (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue))) - { - if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) - { - DBG_8192C("recv_tasklet => bDriverStopped or bSurpriseRemoved \n"); - - break; - } - - - recvbuf2recvframe(padapter, precvbuf); - - rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); - } - -} - -static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) -{ - struct recv_buf *precvbuf = (struct recv_buf *)purb->context; - _adapter *padapter =(_adapter *)precvbuf->adapter; - struct recv_priv *precvpriv = &padapter->recvpriv; - - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n")); - - precvpriv->rx_pending_cnt --; - - if (RTW_CANNOT_RX(padapter)) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved)); - - goto exit; - } - - if(purb->status==0)//SUCCESS - { - if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n")); - - rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); - } - else - { - rtw_reset_continual_io_error(adapter_to_dvobj(padapter)); - - precvbuf->transfer_len = purb->actual_length; - - //rtw_enqueue_rx_transfer_buffer(precvpriv, rx_transfer_buf); - rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue); - - tasklet_schedule(&precvpriv->recv_tasklet); - } - } - else - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status)); - - DBG_8192C("###=> usb_read_port_complete => urb status(%d)\n", purb->status); - - if(rtw_inc_and_chk_continual_io_error(adapter_to_dvobj(padapter)) == _TRUE ){ - padapter->bSurpriseRemoved = _TRUE; - } - - switch(purb->status) { - case -EINVAL: - case -EPIPE: - case -ENODEV: - case -ESHUTDOWN: - //padapter->bSurpriseRemoved=_TRUE; - //RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n")); - case -ENOENT: - padapter->bDriverStopped=_TRUE; - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n")); - break; - case -EPROTO: - case -EILSEQ: - case -ETIME: - case -ECOMM: - case -EOVERFLOW: - #ifdef DBG_CONFIG_ERROR_DETECT - { - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL; - } - #endif - rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); - break; - case -EINPROGRESS: - DBG_8192C("ERROR: URB IS IN PROGRESS!/n"); - break; - default: - break; - } - - } - -exit: - -_func_exit_; - -} - -static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) -{ - int err; - unsigned int pipe; - u32 ret = _SUCCESS; - PURB purb = NULL; - struct recv_buf *precvbuf = (struct recv_buf *)rmem; - _adapter *adapter = pintfhdl->padapter; - struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); - struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); - struct recv_priv *precvpriv = &adapter->recvpriv; - struct usb_device *pusbd = pdvobj->pusbdev; - -_func_enter_; - - if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( RTW_CANNOT_RX ) || precvbuf == NULL!!!\n")); - return _FAIL; - } - - rtl8723bu_init_recvbuf(adapter, precvbuf); - - if(precvbuf->pbuf) - { - precvpriv->rx_pending_cnt++; - - purb = precvbuf->purb; - - //translate DMA FIFO addr to pipehandle - pipe = ffaddr2pipehdl(pdvobj, addr); - - usb_fill_bulk_urb(purb, pusbd, pipe, - precvbuf->pbuf, - MAX_RECVBUF_SZ, - usb_read_port_complete, - precvbuf);//context is precvbuf - - purb->transfer_dma = precvbuf->dma_transfer_addr; - purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - err = usb_submit_urb(purb, GFP_ATOMIC); - if((err) && (err != (-EPERM))) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status)); - DBG_8192C("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status); - ret = _FAIL; - } - - } - -_func_exit_; - - return ret; -} -#else // CONFIG_USE_USB_BUFFER_ALLOC_RX - - -void rtl8723bu_recv_tasklet(void *priv) -{ - _pkt *pskb; - _adapter *padapter = (_adapter*)priv; - struct recv_priv *precvpriv = &padapter->recvpriv; - struct recv_buf *precvbuf = NULL; - - while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) - { - if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) - { - DBG_8192C("recv_tasklet => bDriverStopped or bSurpriseRemoved \n"); -#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER - if(rtw_free_skb_premem(pskb)!=0) -#endif //CONFIG_PREALLOC_RX_SKB_BUFFER - - rtw_skb_free(pskb); - break; - } - - recvbuf2recvframe(padapter, pskb); - -#ifdef CONFIG_PREALLOC_RECV_SKB - - skb_reset_tail_pointer(pskb); - - pskb->len = 0; - - skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); - -#else - rtw_skb_free(pskb); -#endif - - } - while (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue))) - { - DBG_871X("dequeue_recvbuf %p\n", precvbuf); - precvbuf->pskb = NULL; - precvbuf->reuse = _FALSE; - rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); - } - -} - - -static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) -{ - _irqL irqL; - uint isevt, *pbuf; - struct recv_buf *precvbuf = (struct recv_buf *)purb->context; - _adapter *padapter =(_adapter *)precvbuf->adapter; - struct recv_priv *precvpriv = &padapter->recvpriv; - - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n")); - - //_enter_critical(&precvpriv->lock, &irqL); - //precvbuf->irp_pending=_FALSE; - //precvpriv->rx_pending_cnt --; - //_exit_critical(&precvpriv->lock, &irqL); - - precvpriv->rx_pending_cnt --; - - //if(precvpriv->rx_pending_cnt== 0) - //{ - // RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: rx_pending_cnt== 0, set allrxreturnevt!\n")); - // _rtw_up_sema(&precvpriv->allrxreturnevt); - //} - - if(RTW_CANNOT_RX(padapter)) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved)); - - #ifdef CONFIG_PREALLOC_RECV_SKB - precvbuf->reuse = _TRUE; - #else - if(precvbuf->pskb){ - DBG_8192C("==> free skb(%p)\n",precvbuf->pskb); - rtw_skb_free(precvbuf->pskb); - } - #endif - DBG_871X("%s()-%d: RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) \n", - __FUNCTION__, __LINE__,padapter->bDriverStopped, padapter->bSurpriseRemoved); - goto exit; - } - - if(purb->status==0)//SUCCESS - { - if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n")); - precvbuf->reuse = _TRUE; - rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); - DBG_8192C("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__); - } - else - { - rtw_reset_continual_io_error(adapter_to_dvobj(padapter)); - - precvbuf->transfer_len = purb->actual_length; - skb_put(precvbuf->pskb, purb->actual_length); - skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb); - - if (skb_queue_len(&precvpriv->rx_skb_queue)<=1) - tasklet_schedule(&precvpriv->recv_tasklet); - - precvbuf->pskb = NULL; - precvbuf->reuse = _FALSE; - rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); - } - } - else - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status)); - - DBG_8192C("###=> usb_read_port_complete => urb status(%d)\n", purb->status); - - if(rtw_inc_and_chk_continual_io_error(adapter_to_dvobj(padapter)) == _TRUE ){ - padapter->bSurpriseRemoved = _TRUE; - } - - switch(purb->status) { - case -EINVAL: - case -EPIPE: - case -ENODEV: - case -ESHUTDOWN: - //padapter->bSurpriseRemoved=_TRUE; - //RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n")); - case -ENOENT: - padapter->bDriverStopped=_TRUE; - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n")); - break; - case -EPROTO: - case -EILSEQ: - case -ETIME: - case -ECOMM: - case -EOVERFLOW: - #ifdef DBG_CONFIG_ERROR_DETECT - { - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL; - } - #endif - precvbuf->reuse = _TRUE; - rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); - break; - case -EINPROGRESS: - DBG_8192C("ERROR: URB IS IN PROGRESS!/n"); - break; - default: - break; - } - - } - -exit: - -_func_exit_; - -} - -static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) -{ - _irqL irqL; - int err; - unsigned int pipe; - SIZE_PTR tmpaddr=0; - SIZE_PTR alignment=0; - u32 ret = _SUCCESS; - PURB purb = NULL; - struct recv_buf *precvbuf = (struct recv_buf *)rmem; - _adapter *adapter = pintfhdl->padapter; - struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); - struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); - struct recv_priv *precvpriv = &adapter->recvpriv; - struct usb_device *pusbd = pdvobj->pusbdev; - - -_func_enter_; - - if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( RTW_CANNOT_RX ) || precvbuf == NULL!!!\n")); - return _FAIL; - } - -#ifdef CONFIG_PREALLOC_RECV_SKB - if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) - { - if (NULL != (precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue))) - { - precvbuf->reuse = _TRUE; - } - } -#endif - - rtl8723bu_init_recvbuf(adapter, precvbuf); - - //re-assign for linux based on skb - if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) - { - precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - - if(precvbuf->pskb == NULL) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("init_recvbuf(): alloc_skb fail!\n")); - DBG_8192C("#### usb_read_port() alloc_skb fail! precvbuf=%p #####\n", precvbuf); - //enqueue precvbuf and wait for free skb - rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue); - return _FAIL; - } - - tmpaddr = (SIZE_PTR)precvbuf->pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); - skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); - - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - } - else//reuse skb - { - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - - precvbuf->reuse = _FALSE; - } - - //_enter_critical(&precvpriv->lock, &irqL); - //precvpriv->rx_pending_cnt++; - //precvbuf->irp_pending = _TRUE; - //_exit_critical(&precvpriv->lock, &irqL); - - precvpriv->rx_pending_cnt++; - - purb = precvbuf->purb; - - //translate DMA FIFO addr to pipehandle - pipe = ffaddr2pipehdl(pdvobj, addr); - - usb_fill_bulk_urb(purb, pusbd, pipe, - precvbuf->pbuf, - MAX_RECVBUF_SZ, - usb_read_port_complete, - precvbuf);//context is precvbuf - - err = usb_submit_urb(purb, GFP_ATOMIC); - if((err) && (err != (-EPERM))) - { - RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status)); - DBG_8192C("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status); - ret = _FAIL; - } - -_func_exit_; - - return ret; -} -#endif // CONFIG_USE_USB_BUFFER_ALLOC_RX - - void rtl8723bu_xmit_tasklet(void *priv) { int ret = _FALSE; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/autoconf.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/autoconf.h index de4a2e25afeb..bc11e85c4207 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/autoconf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/autoconf.h @@ -1,7 +1,7 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * + * Copyright(c) 2007 - 2014 Realtek Corporation. All rights reserved. + * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. @@ -17,138 +17,66 @@ * * ******************************************************************************/ -//***** temporarily flag ******* -#define CONFIG_SINGLE_IMG - -//#define CONFIG_DISABLE_ODM - -//***** temporarily flag ******* /* - * Public General Config + * Public General Config */ #define AUTOCONF_INCLUDED + #define RTL871X_MODULE_NAME "8723BU" #define DRV_NAME "rtl8723bu" #ifndef CONFIG_RTL8723B #define CONFIG_RTL8723B #endif -#define BT_30_SUPPORT 1 -#define CONFIG_USB_HCI 1 - +#define CONFIG_USB_HCI -#define PLATFORM_LINUX 1 +#define PLATFORM_LINUX -//#define CONFIG_IOCTL_CFG80211 1 +/* + * Wi-Fi Functions Config + */ +#define CONFIG_80211N_HT +#define CONFIG_RECV_REORDERING_CTRL +//#define CONFIG_IOCTL_CFG80211 // Set from Makefile #ifdef CONFIG_IOCTL_CFG80211 + /* + * Indecate new sta asoc through cfg80211_new_sta + * If kernel version >= 3.2 or + * version < 3.2 but already apply cfg80211 patch, + * RTW_USE_CFG80211_STA_EVENT must be defiend! + */ //#define RTW_USE_CFG80211_STA_EVENT /* Indecate new sta asoc through cfg80211_new_sta */ #define CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER - //#define CONFIG_DEBUG_CFG80211 + //#define CONFIG_DEBUG_CFG80211 //#define CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2 #define CONFIG_SET_SCAN_DENY_TIMER #endif -/* - * Internal General Config - */ -//#define CONFIG_H2CLBK - -#define CONFIG_EMBEDDED_FWIMG 1 -//#define CONFIG_FILE_FWIMG - -#define CONFIG_XMIT_ACK -#ifdef CONFIG_XMIT_ACK - #define CONFIG_ACTIVE_KEEP_ALIVE_CHECK -#endif -#define CONFIG_C2H_PACKET_EN -#define CONFIG_80211N_HT 1 - - -#define CONFIG_RECV_REORDERING_CTRL 1 - -//#define CONFIG_TCP_CSUM_OFFLOAD_RX 1 - -//#define CONFIG_DRVEXT_MODULE 1 - - - //#define CONFIG_SUPPORT_USB_INT - #ifdef CONFIG_SUPPORT_USB_INT -//#define CONFIG_USB_INTERRUPT_IN_PIPE 1 -#endif - - -#define CONFIG_IPS 1 -#ifdef CONFIG_IPS - //#define CONFIG_IPS_LEVEL_2 1 //enable this to set default IPS mode to IPS_LEVEL_2 -#endif -//#define SUPPORT_HW_RFOFF_DETECTED 1 - -#define CONFIG_LPS 1 -#if defined(CONFIG_LPS) && defined(CONFIG_SUPPORT_USB_INT) - //#define CONFIG_LPS_LCLK 1 -#endif - -#ifdef CONFIG_LPS_LCLK - #define CONFIG_XMIT_THREAD_MODE -#endif - -//befor link -//#define CONFIG_ANTENNA_DIVERSITY - -//after link -#ifdef CONFIG_ANTENNA_DIVERSITY - #define CONFIG_HW_ANTENNA_DIVERSITY -#endif - - -//#define CONFIG_CONCURRENT_MODE 1 -#ifdef CONFIG_CONCURRENT_MODE - //#define CONFIG_HWPORT_SWAP //Port0->Sec , Port1 -> Pri - #define CONFIG_RUNTIME_PORT_SWITCH - //#define DBG_RUNTIME_PORT_SWITCH - #define CONFIG_STA_MODE_SCAN_UNDER_AP_MODE - //#define CONFIG_TSF_RESET_OFFLOAD 1 // For 2 PORT TSF SYNC. - - //#define CONFIG_MULTI_VIR_IFACES //besides primary&secondary interfaces, extend to support more interfaces -#endif - -//#define CONFIG_IOL - - -#define CONFIG_AP_MODE 1 +#define CONFIG_AP_MODE #ifdef CONFIG_AP_MODE - //#define CONFIG_INTERRUPT_BASED_TXBCN // Tx Beacon when driver BCN_OK ,BCN_ERR interrupt occurs - #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_INTERRUPT_BASED_TXBCN) - #undef CONFIG_INTERRUPT_BASED_TXBCN - #endif - #ifdef CONFIG_INTERRUPT_BASED_TXBCN - //#define CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT - #define CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR - #endif - #define CONFIG_NATIVEAP_MLME #ifndef CONFIG_NATIVEAP_MLME - #define CONFIG_HOSTAPD_MLME 1 - #endif - //#define CONFIG_FIND_BEST_CHANNEL 1 - //#define CONFIG_NO_WIRELESS_HANDLERS 1 - - //#define CONFIG_AUTO_AP_MODE + #define CONFIG_HOSTAPD_MLME + #endif + //#define CONFIG_FIND_BEST_CHANNEL + //#define CONFIG_NO_WIRELESS_HANDLERS + #define CONFIG_TX_MCAST2UNI // Support IP multicast->unicast + //#define CONFIG_AUTO_AP_MODE #endif -#define CONFIG_P2P 1 +#define CONFIG_P2P #ifdef CONFIG_P2P + //Added by Albert 20110812 //The CONFIG_WFD is for supporting the Wi-Fi display #define CONFIG_WFD - + #ifndef CONFIG_WIFI_TEST #define CONFIG_P2P_REMOVE_GROUP_INFO #endif //#define CONFIG_DBG_P2P - #define CONFIG_P2P_PS //#define CONFIG_P2P_IPS #define CONFIG_P2P_OP_CHK_SOCIAL_CH @@ -156,18 +84,38 @@ #define CONFIG_P2P_INVITE_IOT #endif -// Added by Kurt 20110511 -//#define CONFIG_TDLS 1 +// Added by Kurt 20110511 +//#define CONFIG_TDLS #ifdef CONFIG_TDLS // #ifndef CONFIG_WFD -// #define CONFIG_WFD 1 +// #define CONFIG_WFD // #endif -// #define CONFIG_TDLS_AUTOSETUP 1 -// #define CONFIG_TDLS_AUTOCHECKALIVE 1 +// #define CONFIG_TDLS_AUTOSETUP +// #define CONFIG_TDLS_AUTOCHECKALIVE #endif +//#define CONFIG_CONCURRENT_MODE // Set from Makefile +#ifdef CONFIG_CONCURRENT_MODE + #define CONFIG_TSF_RESET_OFFLOAD // For 2 PORT TSF SYNC. + //#define CONFIG_HWPORT_SWAP // Port0->Sec , Port1 -> Pri + #define CONFIG_RUNTIME_PORT_SWITCH + //#define DBG_RUNTIME_PORT_SWITCH + #define CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + + //#define CONFIG_MULTI_VIR_IFACES //besides primary&secondary interfaces, extend to support more interfaces +#endif // CONFIG_CONCURRENT_MODE + +#define CONFIG_LAYER2_ROAMING +#define CONFIG_LAYER2_ROAMING_RESUME + +#define CONFIG_80211D + -#define CONFIG_SKB_COPY 1//for amsdu +/* + * Hareware/Firmware Related Config + */ +//#define CONFIG_ANTENNA_DIVERSITY // Set from Makefile +//#define SUPPORT_HW_RFOFF_DETECTED #define CONFIG_LED #ifdef CONFIG_LED @@ -177,6 +125,20 @@ #endif #endif // CONFIG_LED +#define CONFIG_XMIT_ACK +#ifdef CONFIG_XMIT_ACK + #define CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#endif + +#define CONFIG_C2H_PACKET_EN + +#define CONFIG_RF_GAIN_OFFSET + +#define DISABLE_BB_RF 0 + +#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */ + +//#define CONFIG_IOL #ifdef CONFIG_IOL #define CONFIG_IOL_READ_EFUSE_MAP //#define DBG_IOL_READ_EFUSE_MAP @@ -184,96 +146,164 @@ #endif -#define USB_INTERFERENCE_ISSUE // this should be checked in all usb interface -#define CONFIG_GLOBAL_UI_PID - -#define CONFIG_LAYER2_ROAMING -#define CONFIG_LAYER2_ROAMING_RESUME -//#define CONFIG_ADAPTOR_INFO_CACHING_FILE // now just applied on 8192cu only, should make it general... -#define CONFIG_RESUME_IN_WORKQUEUE -//#define CONFIG_SET_SCAN_DENY_TIMER -#define CONFIG_LONG_DELAY_ISSUE -#define CONFIG_NEW_SIGNAL_STAT_PROCESS -//#define CONFIG_SIGNAL_DISPLAY_DBM //display RX signal with dbm -#ifdef CONFIG_SIGNAL_DISPLAY_DBM -//#define CONFIG_BACKGROUND_NOISE_MONITOR -#endif -#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */ - -#define CONFIG_BR_EXT 1 // Enable NAT2.5 support for STA mode interface with a L2 Bridge -#ifdef CONFIG_BR_EXT -#define CONFIG_BR_EXT_BRNAME "br0" -#endif // CONFIG_BR_EXT +/* + * Interface Related Config + */ +#define CONFIG_USB_TX_AGGREGATION +//#define CONFIG_USB_RX_AGGREGATION -#define CONFIG_TX_MCAST2UNI 1 // Support IP multicast->unicast -//#define CONFIG_CHECK_AC_LIFETIME 1 // Check packet lifetime of 4 ACs. +#define USB_INTERFERENCE_ISSUE // this should be checked in all usb interface -#define CONFIG_RF_GAIN_OFFSET +#define CONFIG_GLOBAL_UI_PID +#define CONFIG_OUT_EP_WIFI_MODE -/* - * Interface Related Config - */ +#define ENABLE_USB_DROP_INCORRECT_OUT -#ifndef CONFIG_MINIMAL_MEMORY_USAGE - #define CONFIG_USB_TX_AGGREGATION 1 -// #define CONFIG_USB_RX_AGGREGATION 1 +//#define CONFIG_SUPPORT_USB_INT +#ifdef CONFIG_SUPPORT_USB_INT +//#define CONFIG_USB_INTERRUPT_IN_PIPE #endif -#define CONFIG_PREALLOC_RECV_SKB 1 -//#define CONFIG_REDUCE_USB_TX_INT 1 // Trade-off: Improve performance, but may cause TX URBs blocked by USB Host/Bus driver on few platforms. -//#define CONFIG_EASY_REPLACEMENT 1 +//#define CONFIG_REDUCE_USB_TX_INT // Trade-off: Improve performance, but may cause TX URBs blocked by USB Host/Bus driver on few platforms. -/* +/* * CONFIG_USE_USB_BUFFER_ALLOC_XX uses Linux USB Buffer alloc API and is for Linux platform only now! */ -//#define CONFIG_USE_USB_BUFFER_ALLOC_TX 1 // Trade-off: For TX path, improve stability on some platforms, but may cause performance degrade on other platforms. -//#define CONFIG_USE_USB_BUFFER_ALLOC_RX 1 // For RX path +//#define CONFIG_USE_USB_BUFFER_ALLOC_TX // Trade-off: For TX path, improve stability on some platforms, but may cause performance degrade on other platforms. +//#define CONFIG_USE_USB_BUFFER_ALLOC_RX // For RX path -#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX -#undef CONFIG_PREALLOC_RECV_SKB -#endif - - -/* +/* * USB VENDOR REQ BUFFER ALLOCATION METHOD * if not set we'll use function local variable (stack memory) */ //#define CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE #define CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC - #define CONFIG_USB_VENDOR_REQ_MUTEX #define CONFIG_VENDOR_REQ_RETRY - -//#define CONFIG_USB_SUPPORT_ASYNC_VDN_REQ 1 +//#define CONFIG_USB_SUPPORT_ASYNC_VDN_REQ /* - * HAL Related Config + * Others */ +#define CONFIG_SKB_COPY //for amsdu -#define CONFIG_OUT_EP_WIFI_MODE 0 +#define CONFIG_PREALLOC_RECV_SKB -#define ENABLE_USB_DROP_INCORRECT_OUT +//#define CONFIG_EASY_REPLACEMENT + +//#define CONFIG_ADAPTOR_INFO_CACHING_FILE // now just applied on 8192cu only, should make it general... -//#define RTL8192CU_ADHOC_WORKAROUND_SETTING 1 +//#define CONFIG_RESUME_IN_WORKQUEUE -#define DISABLE_BB_RF 0 +//#define CONFIG_SET_SCAN_DENY_TIMER + +#define CONFIG_NEW_SIGNAL_STAT_PROCESS + +//#define CONFIG_SIGNAL_DISPLAY_DBM //display RX signal with dbm +#ifdef CONFIG_SIGNAL_DISPLAY_DBM +//#define CONFIG_BACKGROUND_NOISE_MONITOR +#endif + +//#define CONFIG_CHECK_AC_LIFETIME // Check packet lifetime of 4 ACs. + +#define CONFIG_EMBEDDED_FWIMG +//#define CONFIG_FILE_FWIMG + +#define CONFIG_LONG_DELAY_ISSUE +#define CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR + +// Android L(5.0) support +#define CONFIG_RADIO_WORK + + +/* + * Auto Config Section + */ +#ifdef CONFIG_MINIMAL_MEMORY_USAGE + #undef CONFIG_USB_TX_AGGREGATION + #undef CONFIG_USB_RX_AGGREGATION +#endif #ifdef CONFIG_MP_INCLUDED - #define MP_DRIVER 1 - #define CONFIG_MP_IWPRIV_SUPPORT 1 + #define MP_DRIVER 1 + #define CONFIG_MP_IWPRIV_SUPPORT //#undef CONFIG_USB_TX_AGGREGATION //#undef CONFIG_USB_RX_AGGREGATION +#else // !CONFIG_MP_INCLUDED + #define MP_DRIVER 0 +#endif // !CONFIG_MP_INCLUDED + +#ifdef CONFIG_POWER_SAVING + #define CONFIG_IPS + #define CONFIG_LPS + + #ifdef CONFIG_IPS + //#define CONFIG_IPS_LEVEL_2 1 //enable this to set default IPS mode to IPS_LEVEL_2 + #endif + + #if defined(CONFIG_LPS) && defined(CONFIG_SUPPORT_USB_INT) + //#define CONFIG_LPS_LCLK + #endif + + #ifdef CONFIG_LPS_LCLK + #define CONFIG_XMIT_THREAD_MODE + #endif +#endif // CONFIG_POWER_SAVING + +#ifdef CONFIG_BT_COEXIST + // for ODM and outsrc BT-Coex + #define BT_30_SUPPORT 1 + + #ifndef CONFIG_LPS + #define CONFIG_LPS // download reserved page to FW + #endif + + #ifndef CONFIG_C2H_PACKET_EN + #define CONFIG_C2H_PACKET_EN + #endif +#else // !CONFIG_BT_COEXIST + #define BT_30_SUPPORT 0 +#endif // !CONFIG_BT_COEXIST + +#ifdef CONFIG_WOWLAN + //#define CONFIG_GTK_OL +#endif // CONFIG_WOWLAN + +#ifdef CONFIG_GPIO_WAKEUP + #ifndef WAKEUP_GPIO_IDX + #define WAKEUP_GPIO_IDX 14 // WIFI Chip Side + #endif // !WAKEUP_GPIO_IDX + #define CONFIG_GPIO_WAKEUP_LOW_ACTIVE // mark this for HIGH active +#endif // CONFIG_GPIO_WAKEUP + +#ifdef CONFIG_AP_MODE + //#define CONFIG_INTERRUPT_BASED_TXBCN // Tx Beacon when driver BCN_OK ,BCN_ERR interrupt occurs + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_INTERRUPT_BASED_TXBCN) + #undef CONFIG_INTERRUPT_BASED_TXBCN + #endif + #ifdef CONFIG_INTERRUPT_BASED_TXBCN + //#define CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + #define CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + #endif +#endif // CONFIG_AP_MODE + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + #undef CONFIG_PREALLOC_RECV_SKB #else - #define MP_DRIVER 0 + #ifdef CONFIG_PREALLOC_RECV_SKB +// #define CONFIG_FIX_NR_BULKIN_BUFFER // only use USB prealloc_recv_buffer, no use alloc_skb() + #endif #endif +#ifdef CONFIG_USB_TX_AGGREGATION +//#define CONFIG_TX_EARLY_MODE +#endif -/* - * Platform Related Config - */ - +#ifdef CONFIG_TX_EARLY_MODE +#define RTL8723B_EARLY_MODE_PKT_NUM_10 0 +#endif /* @@ -282,16 +312,16 @@ #define TESTCHIP_SUPPORT 0 -#define RTL8192CE_SUPPORT 0 -#define RTL8192CU_SUPPORT 0 -#define RTL8192C_SUPPORT (RTL8192CE_SUPPORT|RTL8192CU_SUPPORT) +#define RTL8192CE_SUPPORT 0 +#define RTL8192CU_SUPPORT 0 +#define RTL8192C_SUPPORT (RTL8192CE_SUPPORT|RTL8192CU_SUPPORT) -#define RTL8192DE_SUPPORT 0 -#define RTL8192DU_SUPPORT 0 -#define RTL8192D_SUPPORT (RTL8192DE_SUPPORT|RTL8192DU_SUPPORT) +#define RTL8192DE_SUPPORT 0 +#define RTL8192DU_SUPPORT 0 +#define RTL8192D_SUPPORT (RTL8192DE_SUPPORT|RTL8192DU_SUPPORT) -#define RTL8723AU_SUPPORT 0 #define RTL8723AS_SUPPORT 0 +#define RTL8723AU_SUPPORT 0 #define RTL8723AE_SUPPORT 0 #define RTL8723A_SUPPORT (RTL8723AU_SUPPORT|RTL8723AS_SUPPORT|RTL8723AE_SUPPORT) #define RTL8723_FPGA_VERIFICATION 0 @@ -302,26 +332,20 @@ #define RTL8723B_SUPPORT 1 #define RTL8192E_SUPPORT 0 #define RTL8814A_SUPPORT 0 +#define RTL8195A_SUPPORT 0 -#define RATE_ADAPTIVE_SUPPORT 0 +#define RATE_ADAPTIVE_SUPPORT 0 #define POWER_TRAINING_ACTIVE 0 -#ifdef CONFIG_USB_TX_AGGREGATION -//#define CONFIG_TX_EARLY_MODE +#ifdef CONFIG_ANTENNA_DIVERSITY +#define CONFIG_HW_ANTENNA_DIVERSITY #endif -#ifdef CONFIG_TX_EARLY_MODE -#define RTL8723B_EARLY_MODE_PKT_NUM_10 0 -#endif - -#define CONFIG_80211D - -#define CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR /* * Debug Related Config */ -//#define CONFIG_DEBUG /* DBG_871X, etc... */ +#define CONFIG_DEBUG /* DBG_871X, etc... */ #ifdef CONFIG_DEBUG #define DBG 1 // for ODM & BTCOEX debug @@ -349,8 +373,7 @@ //#define DBG_RX_DROP_FRAME //#define DBG_RX_SEQ //#define DBG_RX_SIGNAL_DISPLAY_PROCESSING -//#define DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED "jeff-ap" - +//#define DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED "rtw-ap" //#define DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_conf.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_conf.h index 490b5ebc2c30..b93d60db9449 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_conf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_conf.h @@ -77,18 +77,36 @@ #define DYNAMIC_CAMID_ALLOC +#define RTW_SCAN_SPARSE_MIRACAST 1 +#define RTW_SCAN_SPARSE_BG 0 + #ifndef CONFIG_RTW_HIQ_FILTER #define CONFIG_RTW_HIQ_FILTER 1 #endif #ifndef CONFIG_RTW_ADAPTIVITY_EN - #define CONFIG_RTW_ADAPTIVITY_EN 2 + #define CONFIG_RTW_ADAPTIVITY_EN 0 #endif #ifndef CONFIG_RTW_ADAPTIVITY_MODE #define CONFIG_RTW_ADAPTIVITY_MODE 0 #endif +#ifndef CONFIG_RTW_NHM_EN + #define CONFIG_RTW_NHM_EN 0 +#endif + +#ifndef CONFIG_RTW_AMPLIFIER_TYPE_2G + #define CONFIG_RTW_AMPLIFIER_TYPE_2G 0 +#endif + +#ifndef CONFIG_RTW_AMPLIFIER_TYPE_5G + #define CONFIG_RTW_AMPLIFIER_TYPE_5G 0 +#endif + +#define MACID_NUM_SW_LIMIT 32 +#define CAM_ENTRY_NUM_SW_LIMIT 32 + //#include #endif // __DRV_CONF_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_types.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_types.h index 8aaaa4901197..ea6ce92aff08 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_types.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/drv_types.h @@ -94,6 +94,7 @@ typedef struct _ADAPTER _adapter, ADAPTER,*PADAPTER; #include #include #include +#include "../hal/hal_dm.h" #include #include #include @@ -145,10 +146,6 @@ typedef struct _ADAPTER _adapter, ADAPTER,*PADAPTER; #include #endif // CONFIG_IOL -#ifdef CONFIG_IOCTL_CFG80211 -#include "ioctl_cfg80211.h" -#endif //CONFIG_IOCTL_CFG80211 - #include #include #include @@ -329,12 +326,24 @@ struct registry_priv u8 hiq_filter; u8 adaptivity_en; u8 adaptivity_mode; + u8 nhm_en; }; //For registry parameters #define RGTRY_OFT(field) ((ULONG)FIELD_OFFSET(struct registry_priv,field)) #define RGTRY_SZ(field) sizeof(((struct registry_priv*) 0)->field) + +#define GetRegAmplifierType2G(_Adapter) (_Adapter->registrypriv.AmplifierType_2G) +#define GetRegAmplifierType5G(_Adapter) (_Adapter->registrypriv.AmplifierType_5G) + +#define GetRegTxBBSwing_2G(_Adapter) (_Adapter->registrypriv.TxBBSwing_2G) +#define GetRegTxBBSwing_5G(_Adapter) (_Adapter->registrypriv.TxBBSwing_5G) + +#define GetRegbENRFEType(_Adapter) (_Adapter->registrypriv.bEn_RFE) +#define GetRegRFEType(_Adapter) (_Adapter->registrypriv.RFE_Type) + + #define BSSID_OFT(field) ((ULONG)FIELD_OFFSET(WLAN_BSSID_EX,field)) #define BSSID_SZ(field) sizeof(((PWLAN_BSSID_EX) 0)->field) @@ -361,6 +370,8 @@ struct registry_priv #define GET_IFACE_NUMS(padapter) (((_adapter *)padapter)->dvobj->iface_nums) #define GET_ADAPTER(padapter, iface_id) (((_adapter *)padapter)->dvobj->padapters[iface_id]) +#define GetDefaultAdapter(padapter) padapter + enum _IFACE_ID { IFACE_ID0, //maping to PRIMARY_ADAPTER IFACE_ID1, //maping to SECONDARY_ADAPTER @@ -568,6 +579,28 @@ struct cam_entry_cache { ((u8*)(x))[6],((u8*)(x))[7],((u8*)(x))[8],((u8*)(x))[9],((u8*)(x))[10],((u8*)(x))[11], \ ((u8*)(x))[12],((u8*)(x))[13],((u8*)(x))[14],((u8*)(x))[15] +struct macid_bmp { + u32 m0; +#if (MACID_NUM_SW_LIMIT > 32) + u32 m1; +#endif +#if (MACID_NUM_SW_LIMIT > 64) + u32 m2; +#endif +#if (MACID_NUM_SW_LIMIT > 96) + u32 m3; +#endif +}; + +struct macid_ctl_t { + _lock lock; + u8 num; + struct macid_bmp used; + struct macid_bmp bmc; + struct macid_bmp if_g[IFACE_ID_MAX]; + struct macid_bmp ch_g[2]; /* 2 ch concurrency */ +}; + struct dvobj_priv { /*-------- below is common data --------*/ @@ -578,11 +611,6 @@ struct dvobj_priv struct debug_priv drv_dbg; - //for local/global synchronization - // - _lock lock; - int macid[NUM_STA]; - _mutex hw_init_mutex; _mutex h2c_fwcmd_mutex; _mutex setch_mutex; @@ -599,6 +627,8 @@ struct dvobj_priv _adapter *padapters[IFACE_ID_MAX]; u8 iface_nums; // total number of ifaces used runtime + struct macid_ctl_t macid_ctl; + struct cam_ctl_t cam_ctl; struct cam_entry_cache cam_cache[TOTAL_CAM_ENTRY]; @@ -727,6 +757,8 @@ struct dvobj_priv #define dvobj_to_pwrctl(dvobj) (&(dvobj->pwrctl_priv)) #define pwrctl_to_dvobj(pwrctl) container_of(pwrctl, struct dvobj_priv, pwrctl_priv) +#define dvobj_to_macidctl(dvobj) (&(dvobj->macid_ctl)) +#define dvobj_to_regsty(dvobj) (&(dvobj->if1->registrypriv)) #ifdef PLATFORM_LINUX static struct device *dvobj_to_dev(struct dvobj_priv *dvobj) @@ -875,7 +907,9 @@ struct _ADAPTER{ u8 bDriverIsGoingToUnload; u8 init_adpt_in_progress; u8 bHaltInProgress; - +#ifdef CONFIG_GPIO_API + u8 pre_gpio_pin; +#endif _thread_hdl_ cmdThread; _thread_hdl_ evtThread; _thread_hdl_ xmitThread; @@ -1011,12 +1045,13 @@ struct _ADAPTER{ //for debug purpose u8 fix_rate; + u8 data_fb; /* data rate fallback, valid only when fix_rate is not 0xff */ u8 driver_vcs_en; //Enable=1, Disable=0 driver control vrtl_carrier_sense for tx u8 driver_vcs_type;//force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. u8 driver_ampdu_spacing;//driver control AMPDU Density for peer sta's rx u8 driver_rx_ampdu_factor;//0xff: disable drv ctrl, 0:8k, 1:16k, 2:32k, 3:64k; u8 fix_ba_rxbuf_bz; /* 0~127, TODO:consider each sta and each TID */ - + u8 driver_rx_ampdu_spacing; //driver control Rx AMPDU Density unsigned char in_cta_test; #ifdef CONFIG_DBG_COUNTER @@ -1080,12 +1115,6 @@ void rtw_dev_pno_debug(struct net_device *net); #endif //CONFIG_PNO_SET_DEBUG #endif //CONFIG_PNO_SUPPORT -#ifdef CONFIG_GPIO_API -int rtw_get_gpio(struct net_device *netdev, int gpio_num); -int rtw_set_gpio_output_value(struct net_device *netdev, int gpio_num, BOOLEAN isHigh); -int rtw_config_gpio(struct net_device *netdev, int gpio_num, BOOLEAN isOutput); -#endif - #ifdef CONFIG_WOWLAN int rtw_suspend_wow(_adapter *padapter); int rtw_resume_process_wow(_adapter *padapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_btcoex.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_btcoex.h index f12d65548010..84aa63ac49bf 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_btcoex.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_btcoex.h @@ -30,6 +30,7 @@ typedef struct _BT_COEXIST u8 btTotalAntNum; u8 btChipType; u8 bInitlized; + u8 btAntisolation; } BT_COEXIST, *PBT_COEXIST; void DBG_BT_INFO(u8 *dbgmsg); @@ -45,6 +46,7 @@ void hal_btcoex_SetSingleAntPath(PADAPTER padapter, u8 singleAntPath); u8 hal_btcoex_Initialize(PADAPTER padapter); void hal_btcoex_PowerOnSetting(PADAPTER padapter); +void hal_btcoex_PreLoadFirmware(PADAPTER padapter); void hal_btcoex_InitHwConfig(PADAPTER padapter, u8 bWifiOnly); void hal_btcoex_IpsNotify(PADAPTER padapter, u8 type); @@ -76,6 +78,10 @@ void hal_btcoex_SetDBG(PADAPTER, u32 *pDbgModule); u32 hal_btcoex_GetDBG(PADAPTER, u8 *pStrBuf, u32 bufSize); u8 hal_btcoex_IncreaseScanDeviceNum(PADAPTER); u8 hal_btcoex_IsBtLinkExist(PADAPTER); - +void hal_btcoex_SetAntIsolationType(PADAPTER padapter, u8 anttype); +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +int hal_btcoex_AntIsolationConfig_ParaFile(IN PADAPTER Adapter,IN char* pFileName); +int hal_btcoex_ParseAntIsolationConfigFile(PADAPTER Adapter, char* buffer); +#endif // CONFIG_LOAD_PHY_PARA_FROM_FILE #endif // !__HAL_BTCOEX_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com.h index 939763ad15cb..6cb7f717328e 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com.h @@ -189,6 +189,17 @@ typedef enum _FIRMWARE_SOURCE { FW_SOURCE_HEADER_FILE = 1, //from header file } FIRMWARE_SOURCE, *PFIRMWARE_SOURCE; +// +// Queue Select Value in TxDesc +// +#define QSLT_BK 0x2//0x01 +#define QSLT_BE 0x0 +#define QSLT_VI 0x5//0x4 +#define QSLT_VO 0x7//0x6 +#define QSLT_BEACON 0x10 +#define QSLT_HIGH 0x11 +#define QSLT_MGNT 0x12 +#define QSLT_CMD 0x13 // BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. //#define MAX_TX_QUEUE 9 @@ -340,7 +351,7 @@ void rtw_bb_rf_gain_offset(_adapter *padapter); #endif //CONFIG_RF_GAIN_OFFSET void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer); - +u8 rtw_hal_busagg_qsel_check(_adapter *padapter,u8 pre_qsel,u8 next_qsel); void GetHalODMVar( PADAPTER Adapter, HAL_ODM_VARIABLE eVariable, @@ -362,5 +373,21 @@ struct noise_info }; #endif +#ifdef CONFIG_GPIO_API +u8 rtw_hal_get_gpio(_adapter* adapter, u8 gpio_num); +int rtw_hal_set_gpio_output_value(_adapter* adapter, u8 gpio_num, BOOLEAN isHigh); +int rtw_hal_config_gpio(_adapter* adapter, u8 gpio_num, BOOLEAN isOutput); +#endif + +#ifdef CONFIG_GPIO_WAKEUP +void rtw_clear_hostwakeupgpio(PADAPTER padapter); +#endif + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +extern char *rtw_phy_file_path; +extern char file_path[PATH_LENGTH_MAX]; +#define GetLineFromBuffer(buffer) strsep(&buffer, "\n") +#endif + #endif //__HAL_COMMON_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_h2c.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_h2c.h index 7983e4b1af33..8ad82f63d482 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_h2c.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_h2c.h @@ -80,11 +80,14 @@ enum h2c_cmd{ H2C_D0_SCAN_OFFLOAD_INFO = 0x86, H2C_CHNL_SWITCH_OFFLOAD = 0x87, H2C_AOAC_RSVDPAGE3 = 0x88, + H2C_P2P_OFFLOAD_RSVD_PAGE = 0x8A, + H2C_P2P_OFFLOAD = 0x8B, H2C_RESET_TSF = 0xC0, H2C_MAXID, }; +#define H2C_INACTIVE_PS_LEN 3 #define H2C_RSVDPAGE_LOC_LEN 5 #define H2C_MEDIA_STATUS_RPT_LEN 3 #define H2C_KEEP_ALIVE_CTRL_LEN 2 @@ -96,7 +99,7 @@ enum h2c_cmd{ #define H2C_PSTUNEPARAM_LEN 4 #define H2C_MACID_CFG_LEN 7 #define H2C_BTMP_OPER_LEN 4 -#define H2C_WOWLAN_LEN 4 +#define H2C_WOWLAN_LEN 5 #define H2C_REMOTE_WAKE_CTRL_LEN 3 #define H2C_AOAC_GLOBAL_INFO_LEN 2 #define H2C_AOAC_RSVDPAGE_LOC_LEN 7 @@ -107,6 +110,8 @@ enum h2c_cmd{ #define H2C_FORCE_BT_TXPWR_LEN 3 #define H2C_BCN_RSVDPAGE_LEN 5 #define H2C_PROBERSP_RSVDPAGE_LEN 5 +#define H2C_P2PRSVDPAGE_LOC_LEN 5 +#define H2C_P2P_OFFLOAD_LEN 3 #ifdef CONFIG_WOWLAN #define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) @@ -187,7 +192,6 @@ enum h2c_cmd{ #define SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT(__pH2CCmd+1, 0, 8, __Value) #define SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT(__pH2CCmd+2, 0, 8, __Value) -#ifdef CONFIG_AP_WOWLAN //_AP_Offload 0x08 #define SET_H2CCMD_AP_WOWLAN_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT(__pH2CCmd, 0, 8, __Value) //_BCN_RsvdPage 0x09 @@ -207,7 +211,6 @@ enum h2c_cmd{ #define SET_H2CCMD_AP_WOW_PS_32K_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) #define SET_H2CCMD_AP_WOW_PS_RF(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) #define SET_H2CCMD_AP_WOW_PS_DURATION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+1, 0, 8, __Value) -#endif // _WoWLAN PARAM_CMD_0x80 #define SET_H2CCMD_WOWLAN_FUNC_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) @@ -221,8 +224,9 @@ enum h2c_cmd{ #define SET_H2CCMD_WOWLAN_GPIONUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 7, __Value) #define SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 7, 1, __Value) #define SET_H2CCMD_WOWLAN_GPIO_DURATION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+2, 0, 8, __Value) -//#define SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 1, __Value) -#define SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+3, 0, 8, __Value) +#define SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 1, __Value) +#define SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 1, 7, __Value) +#define SET_H2CCMD_WOWLAN_LOWPR_RX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 1, __Value) // _REMOTE_WAKEUP_CMD_0x81 #define SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) @@ -231,6 +235,7 @@ enum h2c_cmd{ #define SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) #define SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) #define SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 7, 1, __Value) +#define SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 1, __Value) #define SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 1, __Value) // AOAC_GLOBAL_INFO_0x82 @@ -258,6 +263,15 @@ enum h2c_cmd{ #define SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+3, 0, 8, __Value) #endif //CONFIG_PNO_SUPPORT +#ifdef CONFIG_P2P_WOWLAN +//P2P_RsvdPage_0x8a +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+2, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+3, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT((__pH2CCmd)+4, 0, 8, __Value) +#endif //CONFIG_P2P_WOWLAN + //---------------------------------------------------------------------------------------------------------// //------------------------------------------- Structure --------------------------------------------------// //---------------------------------------------------------------------------------------------------------// @@ -285,16 +299,35 @@ typedef struct _RSVDPAGE_LOC { u8 LocProbePacket; #endif //CONFIG_PNO_SUPPORT #endif //CONFIG_WOWLAN -#ifdef CONFIG_AP_WOWLAN u8 LocApOffloadBCN; -#endif //CONFIG_AP_WOWLAN +#ifdef CONFIG_P2P_WOWLAN + u8 LocP2PBeacon; + u8 LocP2PProbeRsp; + u8 LocNegoRsp; + u8 LocInviteRsp; + u8 LocPDRsp; +#endif //CONFIG_P2P_WOWLAN } RSVDPAGE_LOC, *PRSVDPAGE_LOC; #endif void dump_TX_FIFO(PADAPTER padapter, u8 page_num, u16 page_size); u8 rtw_check_invalid_mac_address (u8 *mac_addr); +u8 rtw_hal_set_fw_media_status_cmd(_adapter* adapter, u8 mstatus, u8 macid); #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip); void rtw_get_sec_iv(PADAPTER padapter, u8*pcur_dot11txpn, u8 *StaAddr); void rtw_set_sec_pn(_adapter *padapter); + +void rtw_hal_fill_fake_txdesc(_adapter* padapter, u8* pDesc, u32 BufferLen, + u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); + +//WOW command function +u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable); +void rtw_hal_set_fw_wow_related_cmd(_adapter* padapter, u8 enable); +#ifdef CONFIG_P2P_WOWLAN +//H2C 0x8A +u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter* adapter, PRSVDPAGE_LOC rsvdpageloc); +//H2C 0x8B +u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter* adapter); +#endif //CONFIG_P2P_WOWLAN #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_reg.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_reg.h index 16ff4fe05965..6a0faf00c4ab 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_reg.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_com_reg.h @@ -226,13 +226,22 @@ // 0x0400h ~ 0x047Fh Protocol Configuration // //----------------------------------------------------- -#define REG_VOQ_INFORMATION 0x0400 -#define REG_VIQ_INFORMATION 0x0404 -#define REG_BEQ_INFORMATION 0x0408 -#define REG_BKQ_INFORMATION 0x040C -#define REG_MGQ_INFORMATION 0x0410 -#define REG_HGQ_INFORMATION 0x0414 -#define REG_BCNQ_INFORMATION 0x0418 + +/* 92C, 92D */ +#define REG_VOQ_INFO 0x0400 +#define REG_VIQ_INFO 0x0404 +#define REG_BEQ_INFO 0x0408 +#define REG_BKQ_INFO 0x040C + +/* 88E, 8723A, 8812A, 8821A, 92E, 8723B */ +#define REG_Q0_INFO 0x400 +#define REG_Q1_INFO 0x404 +#define REG_Q2_INFO 0x408 +#define REG_Q3_INFO 0x40C + +#define REG_MGQ_INFO 0x0410 +#define REG_HGQ_INFO 0x0414 +#define REG_BCNQ_INFO 0x0418 #define REG_TXPKT_EMPTY 0x041A #define REG_CPU_MGQ_INFORMATION 0x041C #define REG_FWHW_TXQ_CTRL 0x0420 @@ -258,9 +267,19 @@ #define REG_FAST_EDCA_CTRL 0x0460 #define REG_RD_RESP_PKT_TH 0x0463 +/* 8723A, 8812A, 8821A, 92E, 8723B */ +#define REG_Q4_INFO 0x468 +#define REG_Q5_INFO 0x46C +#define REG_Q6_INFO 0x470 +#define REG_Q7_INFO 0x474 + #define REG_INIRTS_RATE_SEL 0x0480 #define REG_INIDATA_RATE_SEL 0x0484 +/* 8723B, 92E, 8812A, 8821A*/ +#define REG_MACID_SLEEP_3 0x0484 +#define REG_MACID_SLEEP_1 0x0488 + #define REG_POWER_STAGE1 0x04B4 #define REG_POWER_STAGE2 0x04B8 #define REG_PKT_VO_VI_LIFE_TIME 0x04C0 @@ -273,8 +292,19 @@ #define REG_RTS_MAX_AGGR_NUM 0x04CB #define REG_BAR_MODE_CTRL 0x04CC #define REG_RA_TRY_RATE_AGG_LMT 0x04CF -#define REG_EARLY_MODE_CONTROL 0x04D0 -#define REG_MACID_SLEEP 0x04D4 + +/* 8723A */ +#define REG_MACID_DROP 0x04D0 + +/* 88E */ +#define REG_EARLY_MODE_CONTROL 0x04D0 + +/* 8723B, 92E, 8812A, 8821A */ +#define REG_MACID_SLEEP_2 0x04D0 + +/* 8723A, 8723B, 92E, 8812A, 8821A */ +#define REG_MACID_SLEEP 0x04D4 + #define REG_NQOS_SEQ 0x04DC #define REG_QOS_SEQ 0x04DE #define REG_NEED_CPU_HANDLE 0x04E0 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_data.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_data.h index 5b8164c44608..ac6007e8977e 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_data.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_data.h @@ -22,7 +22,7 @@ #if 1//def CONFIG_SINGLE_IMG -#include "../hal/OUTSRC/odm_precomp.h" +#include "../hal/OUTSRC/phydm_precomp.h" #ifdef CONFIG_BT_COEXIST #include #endif @@ -75,6 +75,22 @@ typedef enum _INTERFACE_SELECT_USB{ INTF_SEL5_USB_Combo_MF = 5, // USB WiFi+BT Multi-Function Combo, i.e., Proprietary layout(AS-VAU) which is the same as SDIO card } INTERFACE_SELECT_USB, *PINTERFACE_SELECT_USB; +#ifdef CONFIG_USB_HCI +//should be sync with INTERFACE_SELECT_USB +typedef enum _BOARD_TYPE_8192CUSB{ + BOARD_USB_DONGLE = 0, // USB dongle + BOARD_USB_High_PA = 1, // USB dongle with high power PA + BOARD_MINICARD = 2, // Minicard + BOARD_USB_SOLO = 3, // USB solo-Slim module + BOARD_USB_COMBO = 4, // USB Combo-Slim module +} BOARD_TYPE_8192CUSB, *PBOARD_TYPE_8192CUSB; + +#define SUPPORT_HW_RADIO_DETECT(pHalData) \ + (pHalData->BoardType == BOARD_MINICARD||\ + pHalData->BoardType == BOARD_USB_SOLO||\ + pHalData->BoardType == BOARD_USB_COMBO) +#endif + typedef enum _RT_AMPDU_BRUST_MODE{ RT_AMPDU_BRUST_NONE = 0, RT_AMPDU_BRUST_92D = 1, @@ -247,6 +263,7 @@ struct dm_priv // Add for Reading Initial Data Rate SEL Register 0x484 during watchdog. Using for fill tx desc. 2011.3.21 by Thomas u8 INIDATA_RATE[32]; + _lock IQKSpinLock; }; @@ -463,7 +480,6 @@ typedef struct hal_com_data u8 RegReg542; u8 RegCR_1; u8 Reg837; - u8 RegRFPathS1; u16 RegRRSR; u8 CurAntenna; @@ -502,7 +518,7 @@ typedef struct hal_com_data // Auto FSM to Turn On, include clock, isolation, power control for MAC only u8 bMacPwrCtrlOn; - + u8 bDisableTXPowerTraining; u8 RegIQKFWOffload; struct submit_ctx iqk_sctx; @@ -687,7 +703,10 @@ typedef struct hal_com_data #ifdef CONFIG_BACKGROUND_NOISE_MONITOR s16 noise[ODM_MAX_CHANNEL_NUM]; #endif - + + u8 macid_num; + u8 cam_entry_num; + } HAL_DATA_COMMON, *PHAL_DATA_COMMON; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_intf.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_intf.h index 37acfcf5809e..9dadd66cfaac 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_intf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_intf.h @@ -146,6 +146,8 @@ typedef enum _HW_VARIABLES{ HW_VAR_DL_RSVD_PAGE, HW_VAR_MACID_SLEEP, HW_VAR_MACID_WAKEUP, + HW_VAR_DUMP_MAC_QUEUE_INFO, + HW_VAR_ASIX_IOT, }HW_VARIABLES; typedef enum _HAL_DEF_VARIABLE{ @@ -181,6 +183,7 @@ typedef enum _HAL_DEF_VARIABLE{ HAL_DEF_PCI_ASPM_OSC, // Support for ASPM OSC, added by Roger, 2013.03.27. HAL_DEF_MACID_SLEEP, // Support for MACID sleep HAL_DEF_DBG_RX_INFO_DUMP, + HAL_DEF_DBG_DIS_PWT, //disable Tx power training or not. }HAL_DEF_VARIABLE; typedef enum _HAL_ODM_VARIABLE{ @@ -188,6 +191,7 @@ typedef enum _HAL_ODM_VARIABLE{ HAL_ODM_P2P_STATE, HAL_ODM_WIFI_DISPLAY_STATE, HAL_ODM_NOISE_MONITOR, + HAL_ODM_REGULATION, }HAL_ODM_VARIABLE; typedef enum _HAL_INTF_PS_FUNC{ @@ -318,10 +322,16 @@ struct hal_ops { void (*hal_reset_security_engine)(_adapter * adapter); s32 (*c2h_handler)(_adapter *padapter, u8 *c2h_evt); c2h_id_filter c2h_id_filter_ccx; - -#ifdef CONFIG_BT_COEXIST s32 (*fill_h2c_cmd)(PADAPTER, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); -#endif // CONFIG_BT_COEXIST +#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B) + void (*hal_cal_txdesc_chksum)(struct tx_desc *ptxdesc); +#else + void (*hal_cal_txdesc_chksum)(u8 *ptxdesc); +#endif +#ifdef CONFIG_WOWLAN + void (*hal_set_wowlan_fw)(_adapter *adapter, u8 sleep); +#endif //CONFIG_WOWLAN + u8 (*hal_get_tx_buff_rsvd_page_num)(_adapter *adapter, bool wowlan); }; typedef enum _RT_EEPROM_TYPE{ @@ -395,6 +405,9 @@ typedef enum _HARDWARE_TYPE{ #define IS_HARDWARE_TYPE_8192D(_Adapter) \ (IS_HARDWARE_TYPE_8192DE(_Adapter) || IS_HARDWARE_TYPE_8192DU(_Adapter)) +#define IS_HARDWARE_TYPE_OLDER_THAN_8723A(_Adapter) \ +(IS_HARDWARE_TYPE_8192D(_Adapter) || IS_HARDWARE_TYPE_8192C(_Adapter)) + // // RTL8723A Series // @@ -629,12 +642,10 @@ c2h_id_filter rtw_hal_c2h_id_filter_ccx(_adapter *adapter); s32 rtw_hal_is_disable_sw_channel_plan(PADAPTER padapter); -s32 rtw_hal_macid_sleep(PADAPTER padapter, u32 macid); -s32 rtw_hal_macid_wakeup(PADAPTER padapter, u32 macid); +s32 rtw_hal_macid_sleep(PADAPTER padapter, u8 macid); +s32 rtw_hal_macid_wakeup(PADAPTER padapter, u8 macid); -#ifdef CONFIG_BT_COEXIST s32 rtw_hal_fill_h2c_cmd(PADAPTER, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); -#endif // CONFIG_BT_COEXIST #endif //__HAL_INTF_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_pg.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_pg.h index 2019214416f7..9d9911f3cf3b 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_pg.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/hal_pg.h @@ -236,7 +236,7 @@ #define EEPROM_MAC_ADDR_88EU 0xD7 #define EEPROM_VID_88EU 0xD0 #define EEPROM_PID_88EU 0xD2 -#define EEPROM_USB_OPTIONAL_FUNCTION0 0xD4 //92EU is the same +#define EEPROM_USB_OPTIONAL_FUNCTION0 0xD4 //8192EU, 8812AU is the same #define EEPROM_USB_OPTIONAL_FUNCTION0_8811AU 0x104 // RTL88ES diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/ieee80211.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/ieee80211.h index fc293c457598..5dfc421366cb 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/ieee80211.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/ieee80211.h @@ -1671,13 +1671,18 @@ u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 #define for_each_ie(ie, buf, buf_len) \ for (ie = (void*)buf; (((u8*)ie) - ((u8*)buf) + 1) < buf_len; ie = (void*)(((u8*)ie) + *(((u8*)ie)+1) + 2)) -void dump_ies(u8 *buf, u32 buf_len); -void dump_wps_ie(u8 *ie, u32 ie_len); +void dump_ies(void *sel, u8 *buf, u32 buf_len); + +#ifdef CONFIG_80211N_HT +void dump_ht_cap_ie_content(void *sel, u8 *buf, u32 buf_len); +#endif + +void dump_wps_ie(void *sel, u8 *ie, u32 ie_len); #ifdef CONFIG_P2P u32 rtw_get_p2p_merged_ies_len(u8 *in_ie, u32 in_len); int rtw_p2p_merge_ies(u8 *in_ie, u32 in_len, u8 *merge_ie); -void dump_p2p_ie(u8 *ie, u32 ie_len); +void dump_p2p_ie(void *sel, u8 *ie, u32 ie_len); u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen); u8 *rtw_get_p2p_ie_from_scan_queue(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen, u8 frame_type); u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr); @@ -1687,7 +1692,7 @@ void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); #endif #ifdef CONFIG_WFD -void dump_wfd_ie(u8 *ie, u32 ie_len); +void dump_wfd_ie(void *sel, u8 *ie, u32 ie_len); int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen); int rtw_get_wfd_ie_from_scan_queue(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen, u8 frame_type); int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/linux/wireless.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/linux/wireless.h index 955ea8d316e2..d79caeb592bc 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/linux/wireless.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/linux/wireless.h @@ -35,7 +35,13 @@ #endif /****************************** TYPES ******************************/ - +#ifdef CONFIG_COMPAT +struct compat_iw_point { + compat_caddr_t pointer; + __u16 length; + __u16 flags; +}; +#endif /* --------------------------- SUBTYPES --------------------------- */ /* * For all data larger than 16 octets, we need to use a diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_intf.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_intf.h index d67d06c54cf8..805f3b2f5eeb 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_intf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_intf.h @@ -120,6 +120,11 @@ int rtw_ndev_notifier_register(void); void rtw_ndev_notifier_unregister(void); #include "../os_dep/linux/rtw_proc.h" + +#ifdef CONFIG_IOCTL_CFG80211 +#include "../os_dep/linux/ioctl_cfg80211.h" +#endif //CONFIG_IOCTL_CFG80211 + #endif //PLATFORM_LINUX diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_service.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_service.h index 76026b9723ef..b5901766e262 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_service.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/osdep_service.h @@ -118,7 +118,8 @@ enum mstat_f { MSTAT_FUNC_RX_IO = 0x03<<8, MSTAT_FUNC_TX = 0x04<<8, MSTAT_FUNC_RX = 0x05<<8, - MSTAT_FUNC_MAX = 0x06<<8, + MSTAT_FUNC_CFG_VENDOR = 0x06<<8, + MSTAT_FUNC_MAX = 0x07<<8, }; #define mstat_tf_idx(flags) ((flags)&0xff) @@ -252,7 +253,7 @@ void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_a #endif /* CONFIG_USB_HCI */ #endif /* DBG_MEM_ALLOC */ -extern void* rtw_malloc2d(int h, int w, int size); +extern void* rtw_malloc2d(int h, int w, size_t size); extern void rtw_mfree2d(void *pbuf, int h, int w, int size); extern void _rtw_memcpy(void* dec, void* sour, u32 sz); @@ -474,6 +475,8 @@ __inline static u32 bitshift(u32 bitmask) return i; } +#define rtw_min(a, b) ((a>b)?b:a) + #ifndef MAC_FMT #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_cmd.h index 79a1261fafb2..9826d0da30ed 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_cmd.h @@ -80,6 +80,8 @@ enum h2c_cmd_8723B{ H2C_8723B_D0_SCAN_OFFLOAD_CTRL = 0x85, H2C_8723B_D0_SCAN_OFFLOAD_INFO = 0x86, H2C_8723B_CHNL_SWITCH_OFFLOAD = 0x87, + H2C_8723B_P2P_OFFLOAD_RSVD_PAGE = 0x8A, + H2C_8723B_P2P_OFFLOAD = 0x8B, H2C_8723B_RESET_TSF = 0xC0, H2C_8723B_MAXID, @@ -354,12 +356,16 @@ void rtl8723b_set_ap_wowlan_cmd(_adapter* padapter, u8 enable); void SetFwRelatedForWoWLAN8723b(_adapter* padapter, u8 bHostIsGoingtoSleep); #endif//CONFIG_WOWLAN +#ifdef CONFIG_P2P_WOWLAN +void rtl8723b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); +#endif + void rtl8723b_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param); #ifdef CONFIG_TSF_RESET_OFFLOAD u8 rtl8723b_reset_tsf(_adapter *padapter, u8 reset_port); #endif // CONFIG_TSF_RESET_OFFLOAD s32 FillH2CCmd8723B(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); - -#define FillH2CCmd FillH2CCmd8723B +u8 GetTxBufferRsvdPageNum8723B(_adapter *padapter, bool wowlan); #endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_hal.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_hal.h index ee66b1fcbccd..11ccd6ef09f5 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_hal.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_hal.h @@ -127,7 +127,11 @@ typedef struct _RT_8723B_FIRMWARE_HDR #define TX_DMA_SIZE_8723B 0x8000 // 32K(TX) #define RX_DMA_SIZE_8723B 0x4000 // 16K(RX) +#ifdef CONFIG_FW_C2H_DEBUG +#define RX_DMA_RESERVED_SIZE_8723B 0x100 // 256B, reserved for c2h debug message +#else #define RX_DMA_RESERVED_SIZE_8723B 0x80 // 128B, reserved for tx report +#endif #define RX_DMA_BOUNDARY_8723B (RX_DMA_SIZE_8723B - RX_DMA_RESERVED_SIZE_8723B - 1) @@ -157,7 +161,7 @@ typedef struct _RT_8723B_FIRMWARE_HDR #ifdef CONFIG_PNO_SUPPORT #undef WOWLAN_PAGE_NUM_8723B -#define WOWLAN_PAGE_NUM_8723B 0x0d +#define WOWLAN_PAGE_NUM_8723B 0x15 #endif #ifdef CONFIG_AP_WOWLAN @@ -224,6 +228,7 @@ typedef enum _C2H_EVT C2H_8723B_BT_INFO = 9, C2H_HW_INFO_EXCH = 10, C2H_8723B_BT_MP_INFO = 11, + C2H_8723B_P2P_RPORT = 0x16, #ifdef CONFIG_FW_C2H_DEBUG C2H_8723B_FW_DEBUG = 0xff, #endif //CONFIG_FW_C2H_DEBUG @@ -280,13 +285,16 @@ VOID Hal_EfuseParsePackageType_8723B(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLo VOID Hal_EfuseParseVoltage_8723B(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); #ifdef CONFIG_C2H_PACKET_EN -void C2HPacketHandler_8723B(PADAPTER padapter, u8 *pbuffer, u16 length); +void rtl8723b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length); #endif void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc); void SetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val); void GetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val); +#ifdef CONFIG_C2H_PACKET_EN +void SetHwRegWithBuf8723B(PADAPTER padapter, u8 variable, u8 *pbuf, int len); +#endif // CONFIG_C2H_PACKET_EN u8 SetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); u8 GetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); @@ -309,10 +317,6 @@ void rtl8723bs_cancle_checkbthang_workqueue(_adapter * adapter); void rtl8723bs_hal_check_bt_hang(_adapter * adapter); #endif -#ifdef CONFIG_GPIO_WAKEUP -void HalSetOutPutGPIO(PADAPTER padapter, u8 index, u8 OutPutValue); -#endif - int FirmwareDownloadBT(IN PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware); void CCX_FwC2HTxRpt_8723b(PADAPTER padapter, u8 *pdata, u8 len); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_recv.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_recv.h index 6fd991042c0c..4218f50999b3 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_recv.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_recv.h @@ -34,13 +34,8 @@ s32 rtl8723bs_init_recv_priv(PADAPTER padapter); void rtl8723bs_free_recv_priv(PADAPTER padapter); #endif -void rtl8723b_query_rx_phy_status(union recv_frame *prframe, struct phy_stat *pphy_stat); -void rtl8723b_process_phy_info(PADAPTER padapter, void *prframe); - #ifdef CONFIG_USB_HCI -void update_recvframe_attrib(PADAPTER padapter, union recv_frame *precvframe, u8 *prxstat); -void update_recvframe_phyinfo(union recv_frame *precvframe, struct phy_stat *pphy_info); -int rtl8723bu_init_recv_priv(_adapter *padapter); +int rtl8723bu_init_recv_priv(_adapter *padapter); void rtl8723bu_free_recv_priv (_adapter *padapter); void rtl8723bu_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); #endif @@ -50,7 +45,8 @@ s32 rtl8723be_init_recv_priv(PADAPTER padapter); void rtl8723be_free_recv_priv(PADAPTER padapter); #endif -void rtl8723b_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); +void rtl8723b_query_rx_phy_status(union recv_frame *precvframe, struct phy_stat *pphy_status); +void rtl8723b_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_spec.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_spec.h index b1fba0f1b502..aa4bc2cf3552 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_spec.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_spec.h @@ -278,16 +278,12 @@ #define RT_AC_INT_MASKS (IMR_VIDOK_8723B | IMR_VODOK_8723B | IMR_BEDOK_8723B|IMR_BKDOK_8723B) #endif -#endif +//======================================================== +// General definitions +//======================================================== -#ifdef CONFIG_USB_HCI -//should be renamed and moved to another file -typedef enum _BOARD_TYPE_8192CUSB{ - BOARD_USB_DONGLE = 0, // USB dongle - BOARD_USB_High_PA = 1, // USB dongle with high power PA - BOARD_MINICARD = 2, // Minicard - BOARD_USB_SOLO = 3, // USB solo-Slim module - BOARD_USB_COMBO = 4, // USB Combo-Slim module -} BOARD_TYPE_8723BUSB, *PBOARD_TYPE_8723BUSB; +#define MACID_NUM_8723B 128 +#define CAM_ENTRY_NUM_8723B 64 + +#endif /* __RTL8723B_SPEC_H__ */ -#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_xmit.h index 2c5c7076d987..b998233610e2 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtl8723b_xmit.h @@ -20,17 +20,6 @@ #ifndef __RTL8723B_XMIT_H__ #define __RTL8723B_XMIT_H__ -// -// Queue Select Value in TxDesc -// -#define QSLT_BK 0x2//0x01 -#define QSLT_BE 0x0 -#define QSLT_VI 0x5//0x4 -#define QSLT_VO 0x7//0x6 -#define QSLT_BEACON 0x10 -#define QSLT_HIGH 0x11 -#define QSLT_MGNT 0x12 -#define QSLT_CMD 0x13 #define MAX_TID (15) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_android.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_android.h index bdc4d996075c..cc59417397a1 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_android.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_android.h @@ -88,7 +88,7 @@ int rtw_android_cfg80211_pno_setup(struct net_device *net, #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) int rtw_android_wifictrl_func_add(void); void rtw_android_wifictrl_func_del(void); -void* rtw_wl_android_prealloc(int section, unsigned long size); +void* wl_android_prealloc(int section, unsigned long size); int wifi_get_irq_number(unsigned long *irq_flags_ptr); int wifi_set_power(int on, unsigned long msec); @@ -99,5 +99,13 @@ static int rtw_android_wifictrl_func_add(void) { return 0; } static void rtw_android_wifictrl_func_del(void) {} #endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */ +#ifdef CONFIG_GPIO_WAKEUP +#ifdef CONFIG_PLATFORM_INTEL_BYT +int wifi_configure_gpio(void); +#endif //CONFIG_PLATFORM_INTEL_BYT +void wifi_free_gpio(unsigned int gpio); +#endif //CONFIG_GPIO_WAKEUP + + #endif //__RTW_ANDROID_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ap.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ap.h index dccd5faa7b57..ed8598fca746 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ap.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ap.h @@ -33,7 +33,8 @@ void free_mlme_ap_info(_adapter *padapter); //void update_BCNTIM(_adapter *padapter); void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len); void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index); -void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx); +void _update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx, const char *tag); +#define update_beacon(adapter, ie_id, oui, tx) _update_beacon((adapter), (ie_id), (oui), (tx), __func__) void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level); void expire_timeout_chk(_adapter *padapter); void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_btcoex.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_btcoex.h index 9086a61b66d5..e7b2fa0a5d6f 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_btcoex.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_btcoex.h @@ -30,6 +30,7 @@ void rtw_btcoex_Initialize(PADAPTER); void rtw_btcoex_PowerOnSetting(PADAPTER padapter); +void rtw_btcoex_PreLoadFirmware(PADAPTER padapter); void rtw_btcoex_HAL_Initialize(PADAPTER padapter, u8 bWifiOnly); void rtw_btcoex_IpsNotify(PADAPTER, u8 type); void rtw_btcoex_LpsNotify(PADAPTER, u8 type); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_cmd.h index 154cf4080896..eb0e33ea10f1 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_cmd.h @@ -173,6 +173,16 @@ struct P2P_PS_CTWPeriod_t { u8 CTWPeriod; //TU }; +#ifdef CONFIG_P2P_WOWLAN + +struct P2P_WoWlan_Offload_t{ + u8 Disconnect_Wkup_Drv:1; + u8 role:2; + u8 Wps_Config[2]; +}; + +#endif //CONFIG_P2P_WOWLAN + extern u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); extern struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv); extern void rtw_free_cmd_obj(struct cmd_obj *pcmd); @@ -235,6 +245,9 @@ enum LPS_CTRL_TYPE LPS_CTRL_SPECIAL_PACKET=4, LPS_CTRL_LEAVE=5, LPS_CTRL_TRAFFIC_BUSY = 6, + LPS_CTRL_TX_TRAFFIC_LEAVE = 7, + LPS_CTRL_RX_TRAFFIC_LEAVE = 8, + LPS_CTRL_ENTER = 9, }; enum RFINTFS { @@ -952,6 +965,14 @@ struct TDLSoption_param u8 option; }; +/*H2C Handler index: 64 */ +struct RunInThread_param +{ + void (*func)(void*); + void *context; +}; + + #define GEN_CMD_CODE(cmd) cmd ## _CMD_ @@ -1048,6 +1069,8 @@ extern u8 rtw_c2h_packet_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length); extern u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *c2h_evt); //#endif +u8 rtw_run_in_thread_cmd(PADAPTER padapter, void (*func)(void*), void* context); + u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf); extern void rtw_survey_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); @@ -1141,7 +1164,9 @@ enum rtw_h2c_cmd GEN_CMD_CODE(_SetChannelSwitch), /*61*/ GEN_CMD_CODE(_TDLS), /*62*/ GEN_CMD_CODE(_ChkBMCSleepq), /*63*/ - + + GEN_CMD_CODE(_RunInThreadCMD), /*64*/ + MAX_H2CCMD }; @@ -1224,6 +1249,8 @@ struct _cmd_callback rtw_cmd_callback[] = {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/ {GEN_CMD_CODE(_TDLS), NULL},/*62*/ {GEN_CMD_CODE(_ChkBMCSleepq), NULL}, /*63*/ + + {GEN_CMD_CODE(_RunInThreadCMD), NULL},/*64*/ }; #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_debug.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_debug.h index c9545411d892..67edf7f0a6d0 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_debug.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_debug.h @@ -194,6 +194,8 @@ extern void rtl871x_cedbg(const char *fmt, ...); #if defined(_dbgdump) +#define DBG_871X_EXP(level, EXP) do { if (level <= GlobalDebugLevel) EXP; } while (0) + /* with driver-defined prefix */ #undef DBG_871X_LEVEL #define DBG_871X_LEVEL(level, fmt, arg...) \ @@ -334,6 +336,12 @@ void mac_reg_dump(void *sel, _adapter *adapter); void bb_reg_dump(void *sel, _adapter *adapter); void rf_reg_dump(void *sel, _adapter *adapter); +bool rtw_fwdl_test_trigger_chksum_fail(void); +bool rtw_fwdl_test_trigger_wintint_rdy_fail(void); + +u32 rtw_get_wait_hiq_empty_ms(void); +void rtw_sink_rtp_seq_dbg( _adapter *adapter,_pkt *pkt); + #ifdef CONFIG_PROC_DEBUG ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); int proc_get_read_reg(struct seq_file *m, void *v); @@ -357,7 +365,11 @@ int proc_get_ap_info(struct seq_file *m, void *v); int proc_get_adapter_state(struct seq_file *m, void *v); int proc_get_trx_info(struct seq_file *m, void *v); int proc_get_rate_ctl(struct seq_file *m, void *v); +int proc_get_wifi_spec(struct seq_file *m, void *v); ssize_t proc_set_rate_ctl(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_dis_pwt(struct seq_file *m, void *v); +ssize_t proc_set_dis_pwt(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + int proc_get_suspend_resume_info(struct seq_file *m, void *v); ssize_t proc_set_fwdl_test_case(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); @@ -395,14 +407,24 @@ ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t c int proc_get_rx_stbc(struct seq_file *m, void *v); ssize_t proc_set_rx_stbc(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + + +int proc_get_rx_ampdu_factor(struct seq_file *m, void *v); +ssize_t proc_set_rx_ampdu_factor(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +int proc_get_rx_ampdu_density(struct seq_file *m, void *v); +ssize_t proc_set_rx_ampdu_density(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +int proc_get_tx_ampdu_density(struct seq_file *m, void *v); +ssize_t proc_set_tx_ampdu_density(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); #endif /* CONFIG_80211N_HT */ int proc_get_en_fwps(struct seq_file *m, void *v); ssize_t proc_set_en_fwps(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); //int proc_get_two_path_rssi(struct seq_file *m, void *v); -int proc_get_rssi_disp(struct seq_file *m, void *v); -ssize_t proc_set_rssi_disp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +//int proc_get_rssi_disp(struct seq_file *m, void *v); +//ssize_t proc_set_rssi_disp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); #ifdef CONFIG_BT_COEXIST int proc_get_btcoex_dbg(struct seq_file *m, void *v); @@ -434,6 +456,13 @@ int proc_get_rx_ring(struct seq_file *m, void *v); int proc_get_tx_ring(struct seq_file *m, void *v); #endif +#ifdef CONFIG_P2P_WOWLAN +int proc_get_p2p_wowlan_info(struct seq_file *m, void *v); +#endif /* CONFIG_P2P_WOWLAN */ + +int proc_get_new_bcn_max(struct seq_file *m, void *v); +ssize_t proc_set_new_bcn_max(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + #endif /* CONFIG_PROC_DEBUG */ #endif //__RTW_DEBUG_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ht.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ht.h index 40269af8ed05..84b3bfb13443 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ht.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_ht.h @@ -96,29 +96,74 @@ typedef enum _RT_HT_INF1_CAP{ //------------------------------------------------------------ // The HT Control field //------------------------------------------------------------ -#define SET_HT_CTRL_CSI_STEERING(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 6, 2, _val) -#define SET_HT_CTRL_NDP_ANNOUNCEMENT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+3, 0, 1, _val) -#define GET_HT_CTRL_NDP_ANNOUNCEMENT(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+3, 0, 1) +#define SET_HT_CTRL_CSI_STEERING(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_pEleStart))+2, 6, 2, _val) +#define SET_HT_CTRL_NDP_ANNOUNCEMENT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_pEleStart))+3, 0, 1, _val) +#define GET_HT_CTRL_NDP_ANNOUNCEMENT(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+3, 0, 1) // 20/40 BSS Coexist -#define SET_EXT_CAPABILITY_ELE_BSS_COEXIST(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart), 0, 1, _val) -#define GET_EXT_CAPABILITY_ELE_BSS_COEXIST(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart), 0, 1) - - -#define GET_HT_CAPABILITY_ELE_LDPC_CAP(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 0, 1) -#define GET_HT_CAPABILITY_ELE_TX_STBC(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 7, 1) - -#define GET_HT_CAPABILITY_ELE_RX_STBC(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+1, 0, 2) +#define SET_EXT_CAPABILITY_ELE_BSS_COEXIST(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_pEleStart)), 0, 1, _val) +#define GET_EXT_CAPABILITY_ELE_BSS_COEXIST(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 0, 1) + +/* HT Capabilities Info field */ +#define HT_CAP_ELE_CAP_INFO(_pEleStart) ((u8*)(_pEleStart)) +#define GET_HT_CAP_ELE_LDPC_CAP(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 0, 1) +#define GET_HT_CAP_ELE_CHL_WIDTH(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 1, 1) +#define GET_HT_CAP_ELE_SM_PS(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 2, 2) +#define GET_HT_CAP_ELE_GREENFIELD(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 4, 1) +#define GET_HT_CAP_ELE_SHORT_GI20M(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 5, 1) +#define GET_HT_CAP_ELE_SHORT_GI40M(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 6, 1) +#define GET_HT_CAP_ELE_TX_STBC(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart)), 7, 1) +#define GET_HT_CAP_ELE_RX_STBC(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+1, 0, 2) +#define GET_HT_CAP_ELE_DELAYED_BA(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+1, 2, 1) +#define GET_HT_CAP_ELE_MAX_AMSDU_LENGTH(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+1, 3, 1) +#define GET_HT_CAP_ELE_DSSS_CCK_40M(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+1, 4, 1) +#define GET_HT_CAP_ELE_FORTY_INTOLERANT(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+1, 6, 1) +#define GET_HT_CAP_ELE_LSIG_TXOP_PROTECT(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+1, 7, 1) + +#define SET_HT_CAP_ELE_FORTY_INTOLERANT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_pEleStart))+1, 6, 1, _val) + +/* A-MPDU Parameters field */ +#define HT_CAP_ELE_AMPDU_PARA(_pEleStart) (((u8*)(_pEleStart))+2) +#define GET_HT_CAP_ELE_MAX_AMPDU_LEN_EXP(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+2, 0, 2) +#define GET_HT_CAP_ELE_MIN_MPDU_S_SPACE(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+2, 2, 3) + +#define HT_AMPDU_PARA_FMT "%02x " \ + "MAX AMPDU len:%u bytes, MIN MPDU Start Spacing:%u" + +#define HT_AMPDU_PARA_ARG(x) \ + *((u8*)(x)) \ + , (1 << (13+GET_HT_CAP_ELE_MAX_AMPDU_LEN_EXP(((u8*)x)-2)))-1 \ + , GET_HT_CAP_ELE_MIN_MPDU_S_SPACE(((u8*)x)-2) + +/* Supported MCS Set field */ +#define HT_CAP_ELE_SUP_MCS_SET(_pEleStart) (((u8*)(_pEleStart))+3) +#define HT_CAP_ELE_RX_MCS_MAP(_pEleStart) HT_CAP_ELE_SUP_MCS_SET(_pEleStart) +#define GET_HT_CAP_ELE_RX_HIGHEST_DATA_RATE(_pEleStart) LE_BITS_TO_2BYTE(((u8*)(_pEleStart))+13, 0, 10) +#define GET_HT_CAP_ELE_TX_MCS_DEF(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+15, 0, 1) +#define GET_HT_CAP_ELE_TRX_MCS_NEQ(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+15, 1, 1) +#define GET_HT_CAP_ELE_TX_MAX_SS(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+15, 2, 2) +#define GET_HT_CAP_ELE_TX_UEQM(_pEleStart) LE_BITS_TO_1BYTE(((u8*)(_pEleStart))+15, 4, 1) + +#define HT_SUP_MCS_SET_FMT "%02x %02x %02x %02x %02x%02x%02x%02x%02x%02x" \ + /* "\n%02x%02x%02x%02x%02x%02x" */\ + " %uMbps %s%s%s" +#define HT_SUP_MCS_SET_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5], \ + ((u8*)(x))[6],((u8*)(x))[7],((u8*)(x))[8],((u8*)(x))[9] \ + /*,((u8*)(x))[10],((u8*)(x))[11], ((u8*)(x))[12],((u8*)(x))[13],((u8*)(x))[14],((u8*)(x))[15] */\ + , GET_HT_CAP_ELE_RX_HIGHEST_DATA_RATE(((u8*)x)-3) \ + , GET_HT_CAP_ELE_TX_MCS_DEF(((u8*)x)-3) ? "TX_MCS_DEF " : "" \ + , GET_HT_CAP_ELE_TRX_MCS_NEQ(((u8*)x)-3) ? "TRX_MCS_NEQ " : "" \ + , GET_HT_CAP_ELE_TX_UEQM(((u8*)x)-3) ? "TX_UEQM " : "" //TXBF Capabilities -#define SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8 *)(_pEleStart))+21, 3, 1, ((u8)_val) ) -#define SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8 *)(_pEleStart))+21, 4, 1, ((u8)_val) ) -#define SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8 *)(_pEleStart))+21, 10, 1, ((u8)_val) ) -#define SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8 *)(_pEleStart))+21, 15, 2, ((u8)_val) ) +#define SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8*)(_pEleStart))+21, 3, 1, ((u8)_val) ) +#define SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8*)(_pEleStart))+21, 4, 1, ((u8)_val) ) +#define SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8*)(_pEleStart))+21, 10, 1, ((u8)_val) ) +#define SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8*)(_pEleStart))+21, 15, 2, ((u8)_val) ) #define SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(_pEleStart, _val) SET_BITS_TO_LE_4BYTE( ((u8 *)(_pEleStart))+21, 23, 2, ((u8)_val) ) -#define GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(_pEleStart) LE_BITS_TO_4BYTE((_pEleStart)+21, 10, 1) -#define GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(_pEleStart) LE_BITS_TO_4BYTE((_pEleStart)+21, 15, 2) +#define GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(_pEleStart) LE_BITS_TO_4BYTE(((u8*)(_pEleStart))+21, 10, 1) +#define GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(_pEleStart) LE_BITS_TO_4BYTE(((u8*)(_pEleStart))+21, 15, 2) #endif //_RTL871X_HT_H_ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme.h index 891bdaf8f387..1cf2ab1b20f4 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme.h @@ -187,6 +187,16 @@ struct tx_invite_resp_info{ u8 token; // Used to record the dialog token of p2p invitation request frame. }; +#define MIRACAST_DISABLED 0 +#define MIRACAST_SOURCE 1 +#define MIRACAST_SINK 2 +#define MIRACAST_INVALID 3 + +#define is_miracast_enabled(mode) \ + (mode == MIRACAST_SOURCE || mode == MIRACAST_SINK) + +const char *get_miracast_mode_str(int mode); + #ifdef CONFIG_WFD struct wifi_display_info{ @@ -208,7 +218,7 @@ struct wifi_display_info{ // 0 -> WFD Source Device // 1 -> WFD Primary Sink Device enum SCAN_RESULT_TYPE scan_result_type; // Used when P2P is enable. This parameter will impact the scan result. - + u8 stack_wfd_mode; }; #endif //CONFIG_WFD @@ -253,12 +263,34 @@ struct cfg80211_wifidirect_info{ u8 restore_channel; struct ieee80211_channel remain_on_ch_channel; enum nl80211_channel_type remain_on_ch_type; + ATOMIC_T ro_ch_cookie_gen; u64 remain_on_ch_cookie; bool is_ro_ch; u32 last_ro_ch_time; /* this will be updated at the beginning and end of ro_ch */ }; #endif //CONFIG_IOCTL_CFG80211 +#ifdef CONFIG_P2P_WOWLAN + +enum P2P_WOWLAN_RECV_FRAME_TYPE +{ + P2P_WOWLAN_RECV_NEGO_REQ = 0, + P2P_WOWLAN_RECV_INVITE_REQ = 1, + P2P_WOWLAN_RECV_PROVISION_REQ = 2, +}; + +struct p2p_wowlan_info{ + + u8 is_trigger; + enum P2P_WOWLAN_RECV_FRAME_TYPE wowlan_recv_frame_type; + u8 wowlan_peer_addr[ETH_ALEN]; + u16 wowlan_peer_wpsconfig; + u8 wowlan_peer_is_persistent; + u8 wowlan_peer_invitation_type; +}; + +#endif //CONFIG_P2P_WOWLAN + struct wifidirect_info{ _adapter* padapter; _timer find_phase_timer; @@ -284,6 +316,11 @@ struct wifidirect_info{ #ifdef CONFIG_WFD struct wifi_display_info *wfd_info; #endif + +#ifdef CONFIG_P2P_WOWLAN + struct p2p_wowlan_info p2p_wow_info; +#endif //CONFIG_P2P_WOWLAN + enum P2P_ROLE role; enum P2P_STATE pre_p2p_state; enum P2P_STATE p2p_state; @@ -401,6 +438,18 @@ enum { RTW_ROAM_ACTIVE = BIT2, }; +struct beacon_keys { + u8 ssid[IW_ESSID_MAX_SIZE]; + u32 ssid_len; + u8 bcn_channel; + u16 ht_cap_info; + u8 ht_info_infos_0_sco; // bit0 & bit1 in infos[0] is second channel offset + int encryp_protocol; + int pairwise_cipher; + int group_cipher; + int is_8021x; +}; + struct mlme_priv { _lock lock; @@ -431,6 +480,12 @@ struct mlme_priv { struct wlan_network cur_network; struct wlan_network *cur_network_scanned; + + // bcn check info + struct beacon_keys cur_beacon_keys; // save current beacon keys + struct beacon_keys new_beacon_keys; // save new beacon keys + u8 new_beacon_cnts; // if new_beacon_cnts >= threshold, ap beacon is changed + #ifdef CONFIG_ARP_KEEP_ALIVE // for arp offload keep alive u8 gw_mac_addr[6]; @@ -619,8 +674,8 @@ struct mlme_priv { u8 scanning_via_buddy_intf; #endif - u8 NumOfBcnInfoChkFail; - u32 timeBcnInfoChkStart; +// u8 NumOfBcnInfoChkFail; +// u32 timeBcnInfoChkStart; }; #define rtw_mlme_set_auto_scan_int(adapter, ms) \ @@ -786,6 +841,9 @@ extern void rtw_free_assoc_resources(_adapter* adapter, int lock_scanned_queue); extern void rtw_indicate_disconnect(_adapter* adapter); extern void rtw_indicate_connect(_adapter* adapter); void rtw_indicate_scan_done( _adapter *padapter, bool aborted); + +u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms); +void rtw_scan_abort_no_wait(_adapter *adapter); void rtw_scan_abort(_adapter *adapter); extern int rtw_restruct_sec_ie(_adapter *adapter,u8 *in_ie,u8 *out_ie,uint in_len); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme_ext.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme_ext.h index 35381e4c3c51..f5ba9b4414b2 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme_ext.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mlme_ext.h @@ -196,6 +196,7 @@ typedef enum _RT_CHANNEL_DOMAIN RT_CHANNEL_DOMAIN_FCC1_FCC9 = 0x55, RT_CHANNEL_DOMAIN_WORLD_ETSI13 = 0x56, RT_CHANNEL_DOMAIN_FCC1_FCC10 = 0x57, + RT_CHANNEL_DOMAIN_WORLD_MKK4 = 0x58, //===== Add new channel plan above this line===============// RT_CHANNEL_DOMAIN_MAX, RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F, @@ -248,11 +249,15 @@ typedef enum _RT_CHANNEL_DOMAIN_5G RT_CHANNEL_DOMAIN_5G_FCC9 = 0x1D, //(w/o Weather radar) RT_CHANNEL_DOMAIN_5G_ETSI13 = 0x1E, //(w/o Weather radar) RT_CHANNEL_DOMAIN_5G_FCC10 = 0x1F, //Argentina (w/o Weather radar) + RT_CHANNEL_DOMAIN_5G_KCC2 = 0x20, //Korea 5G + RT_CHANNEL_DOMAIN_5G_FCC11 = 0x21, //US/Canada + RT_CHANNEL_DOMAIN_5G_NCC5 = 0x22, //Taiwan + RT_CHANNEL_DOMAIN_5G_MKK4 = 0x23, //Japan W52 //===== Add new channel plan above this line===============// //===== Driver Self Defined =====// - RT_CHANNEL_DOMAIN_5G_FCC = 0x20, - RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS = 0x21, - RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS = 0x22, + RT_CHANNEL_DOMAIN_5G_FCC = 0x30, + RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS = 0x31, + RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS = 0x32, RT_CHANNEL_DOMAIN_5G_MAX, }RT_CHANNEL_DOMAIN_5G, *PRT_CHANNEL_DOMAIN_5G; @@ -487,6 +492,7 @@ struct mlme_ext_info #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH) u8 scan_cnt; + u8 backop_cnt; #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE }; @@ -660,6 +666,7 @@ void SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_ unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); void read_cam(_adapter *padapter ,u8 entry, u8 *get_key); +void dump_cam_table(_adapter *padapter); /* modify HW only */ void _write_cam(_adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key); @@ -711,8 +718,11 @@ void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); void VCS_update(_adapter *padapter, struct sta_info *psta); void update_ldpc_stbc_cap(struct sta_info *psta); -void update_beacon_info(_adapter *padapter, u8 *pframe, uint len, struct sta_info *psta); +int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, + struct beacon_keys *recv_beacon); +void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon); int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len); +void update_beacon_info(_adapter *padapter, u8 *pframe, uint len, struct sta_info *psta); #ifdef CONFIG_DFS void process_csa_ie(_adapter *padapter, u8 *pframe, uint len); #endif //CONFIG_DFS @@ -743,10 +753,22 @@ s16 rtw_get_camid(_adapter *adapter, struct sta_info* sta, s16 kid); s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid); s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid); void rtw_camid_free(_adapter *adapter, u8 cam_id); - -extern void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta); -extern void rtw_release_macid(_adapter *padapter, struct sta_info *psta); -extern u8 rtw_search_max_mac_id(_adapter *padapter); +bool rtw_camid_is_gk(_adapter *padapter, u8 entry); +bool read_phy_cam_is_gtk(_adapter *padapter, u8 entry); + +struct macid_bmp; +struct macid_ctl_t; +void dump_macid_map(void *sel, struct macid_bmp *map, u8 max_num); +bool rtw_macid_is_set(struct macid_bmp *map, u8 id); +bool rtw_macid_is_used(struct macid_ctl_t *macid_ctl, u8 id); +bool rtw_macid_is_bmc(struct macid_ctl_t *macid_ctl, u8 id); +s8 rtw_macid_get_if_g(struct macid_ctl_t *macid_ctl, u8 id); +s8 rtw_macid_get_ch_g(struct macid_ctl_t *macid_ctl, u8 id); +void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta); +void rtw_release_macid(_adapter *padapter, struct sta_info *psta); +u8 rtw_search_max_mac_id(_adapter *padapter); +void rtw_macid_ctl_init(struct macid_ctl_t *macid_ctl); +void rtw_macid_ctl_deinit(struct macid_ctl_t *macid_ctl); void report_join_res(_adapter *padapter, int res); void report_survey_event(_adapter *padapter, union recv_frame *precv_frame); @@ -784,7 +806,7 @@ void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da); s32 issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8* da, u8 ch, bool append_wps, int try_cnt, int wait_ms); int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms); -s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da); +s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode); int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms); int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason); int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt, int wait_ms); @@ -793,6 +815,8 @@ void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char act #ifdef CONFIG_IEEE80211W void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid); #endif //CONFIG_IEEE80211W +int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode); +int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms); unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr); unsigned int send_beacon(_adapter *padapter); @@ -832,7 +856,7 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res); void mlmeext_sta_del_event_callback(_adapter *padapter); void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta); -void linked_status_chk(_adapter *padapter); +void linked_status_chk(_adapter *padapter, u8 from_timer); void _linked_info_dump(_adapter *padapter); @@ -933,6 +957,7 @@ u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf); u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf); u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf); //Kurt: Handling DFS channel switch announcement ie. u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf); +u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf); #define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, @@ -1009,6 +1034,7 @@ struct cmd_hdl wlancmds[] = GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl) /*61*/ GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl) /*62*/ GEN_MLME_EXT_HANDLER(0, chk_bmc_sleepq_hdl) /*63*/ + GEN_MLME_EXT_HANDLER(sizeof(struct RunInThread_param), run_in_thread_hdl) /*64*/ }; #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mp.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mp.h index 3fa8bb232f83..e5f11415a411 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mp.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_mp.h @@ -53,6 +53,7 @@ #define MPT_GET_THERMAL_METER 33 #endif +#define RTWPRIV_VER_INFO 1 #define MAX_MP_XMITBUF_SZ 2048 #define NR_MP_XMITFRAME 8 @@ -347,6 +348,7 @@ enum { CTA_TEST, MP_DISABLE_BT_COEXIST, MP_PwrCtlDM, + MP_GETVER, #ifdef CONFIG_WOWLAN MP_WOW_ENABLE, #endif @@ -563,27 +565,63 @@ typedef enum _MPT_RATE_INDEX MPT_RATE_MCS13, MPT_RATE_MCS14, MPT_RATE_MCS15, /* 27 */ + MPT_RATE_MCS16, + MPT_RATE_MCS17, // #29 + MPT_RATE_MCS18, + MPT_RATE_MCS19, + MPT_RATE_MCS20, + MPT_RATE_MCS21, + MPT_RATE_MCS22, // #34 + MPT_RATE_MCS23, + MPT_RATE_MCS24, + MPT_RATE_MCS25, + MPT_RATE_MCS26, + MPT_RATE_MCS27, // #39 + MPT_RATE_MCS28, // #40 + MPT_RATE_MCS29, // #41 + MPT_RATE_MCS30, // #42 + MPT_RATE_MCS31, // #43 /* VHT rate. Total: 20*/ - MPT_RATE_VHT1SS_MCS0 = 100,// To reserve MCS16~MCS31, the index starts from #100. - MPT_RATE_VHT1SS_MCS1, // #101 + MPT_RATE_VHT1SS_MCS0,// #44 + MPT_RATE_VHT1SS_MCS1, // # MPT_RATE_VHT1SS_MCS2, MPT_RATE_VHT1SS_MCS3, MPT_RATE_VHT1SS_MCS4, MPT_RATE_VHT1SS_MCS5, - MPT_RATE_VHT1SS_MCS6, // #106 + MPT_RATE_VHT1SS_MCS6, // # MPT_RATE_VHT1SS_MCS7, MPT_RATE_VHT1SS_MCS8, - MPT_RATE_VHT1SS_MCS9, - MPT_RATE_VHT2SS_MCS0, - MPT_RATE_VHT2SS_MCS1, // #111 + MPT_RATE_VHT1SS_MCS9, //#53 + MPT_RATE_VHT2SS_MCS0, //#54 + MPT_RATE_VHT2SS_MCS1, MPT_RATE_VHT2SS_MCS2, MPT_RATE_VHT2SS_MCS3, MPT_RATE_VHT2SS_MCS4, MPT_RATE_VHT2SS_MCS5, - MPT_RATE_VHT2SS_MCS6, // #116 + MPT_RATE_VHT2SS_MCS6, MPT_RATE_VHT2SS_MCS7, MPT_RATE_VHT2SS_MCS8, - MPT_RATE_VHT2SS_MCS9, + MPT_RATE_VHT2SS_MCS9, //#63 + MPT_RATE_VHT3SS_MCS0, + MPT_RATE_VHT3SS_MCS1, + MPT_RATE_VHT3SS_MCS2, + MPT_RATE_VHT3SS_MCS3, + MPT_RATE_VHT3SS_MCS4, + MPT_RATE_VHT3SS_MCS5, + MPT_RATE_VHT3SS_MCS6, // #126 + MPT_RATE_VHT3SS_MCS7, + MPT_RATE_VHT3SS_MCS8, + MPT_RATE_VHT3SS_MCS9, + MPT_RATE_VHT4SS_MCS0, + MPT_RATE_VHT4SS_MCS1, // #131 + MPT_RATE_VHT4SS_MCS2, + MPT_RATE_VHT4SS_MCS3, + MPT_RATE_VHT4SS_MCS4, + MPT_RATE_VHT4SS_MCS5, + MPT_RATE_VHT4SS_MCS6, // #136 + MPT_RATE_VHT4SS_MCS7, + MPT_RATE_VHT4SS_MCS8, + MPT_RATE_VHT4SS_MCS9, MPT_RATE_LAST }MPT_RATE_E, *PMPT_RATE_E; @@ -786,6 +824,7 @@ extern void MP_PHY_SetRFPathSwitch(PADAPTER pAdapter ,BOOLEAN bMain); extern ULONG mpt_ProQueryCalTxPower(PADAPTER pAdapter,u8 RfPath); extern void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart); extern u8 MptToMgntRate(u32 MptRateIdx); +extern u8 rtw_mpRateParseFunc(PADAPTER pAdapter, u8 *targetStr); #endif //_RTW_MP_H_ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_odm.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_odm.h index 04543f76db31..a1d81ac4c923 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_odm.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_odm.h @@ -21,7 +21,7 @@ #define __RTW_ODM_H__ #include - +#include "../hal/OUTSRC/phydm_types.h" /* * This file provides utilities/wrappers for rtw driver to use ODM */ @@ -39,5 +39,7 @@ void rtw_odm_adaptivity_parm_msg(void *sel,_adapter *adapter); void rtw_odm_adaptivity_parm_set(_adapter *adapter, s8 TH_L2H_ini, s8 TH_EDCCA_HL_diff, s8 IGI_Base, bool ForceEDCCA, u8 AdapEn_RSSI, u8 IGI_LowerBound); void rtw_odm_get_perpkt_rssi(void *sel, _adapter *adapter); +void rtw_odm_acquirespinlock(_adapter *adapter, RT_SPINLOCK_TYPE type); +void rtw_odm_releasespinlock(_adapter *adapter, RT_SPINLOCK_TYPE type); #endif // __RTW_ODM_H__ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_pwrctrl.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_pwrctrl.h index 8b3f3ab568dc..0eb89fa3bd84 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_pwrctrl.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_pwrctrl.h @@ -63,7 +63,8 @@ enum Power_Mgnt #ifdef CONFIG_PNO_SUPPORT #define MAX_PNO_LIST_COUNT 16 -#define MAX_SCAN_LIST_COUNT 14 //2.4G only +#define MAX_SCAN_LIST_COUNT 14 //2.4G only +#define MAX_HIDDEN_AP 8 //8 hidden AP #endif /* @@ -205,13 +206,15 @@ typedef enum _PS_DENY_REASON typedef struct pno_nlo_info { u32 fast_scan_period; //Fast scan period - u32 ssid_num; //number of entry + u8 ssid_num; //number of entry + u8 hidden_ssid_num; u32 slow_scan_period; //slow scan period u32 fast_scan_iterations; //Fast scan iterations u8 ssid_length[MAX_PNO_LIST_COUNT]; //SSID Length Array u8 ssid_cipher_info[MAX_PNO_LIST_COUNT]; //Cipher information for security u8 ssid_channel_info[MAX_PNO_LIST_COUNT]; //channel information -}pno_nlo_info_t; + u8 loc_probe_req[MAX_HIDDEN_AP]; //loc_probeReq +}pno_nlo_info_t; typedef struct pno_ssid { u32 SSID_len; @@ -316,12 +319,14 @@ struct pwrctrl_priv u8 wowlan_wake_reason; u8 wowlan_ap_mode; u8 wowlan_mode; + u8 wowlan_p2p_mode; #ifdef CONFIG_WOWLAN u8 wowlan_pattern; u8 wowlan_magic; u8 wowlan_unicast; u8 wowlan_pattern_idx; u8 wowlan_pno_enable; + u8 wowlan_from_cmd; #ifdef CONFIG_PNO_SUPPORT u8 pno_in_resume; u8 pno_inited; @@ -430,6 +435,7 @@ void LPS_Enter(PADAPTER padapter, const char *msg); void LPS_Leave(PADAPTER padapter, const char *msg); void traffic_check_for_leave_lps(PADAPTER padapter, u8 tx, u32 tx_packets); void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg); +void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable); void rtw_set_rpwm(_adapter * padapter, u8 val8); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_recv.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_recv.h index ce01eb193e73..dab240e3efdc 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_recv.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_recv.h @@ -384,7 +384,7 @@ struct recv_priv //u8 *pallocated_urb_buf; _sema allrxreturnevt; uint ff_hwaddr; - u8 rx_pending_cnt; + ATOMIC_T rx_pending_cnt; #ifdef CONFIG_USB_INTERRUPT_IN_PIPE #ifdef PLATFORM_LINUX @@ -455,7 +455,7 @@ struct recv_priv struct smooth_rssi_data signal_qual_data; struct smooth_rssi_data signal_strength_data; #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS - + u16 sink_udpport,pre_rtp_rxseq,cur_rtp_rxseq; }; #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_version.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_version.h index 516429f7e088..6bd3f4c78d0d 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_version.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_version.h @@ -1,2 +1,2 @@ -#define DRIVERVERSION "v4.3.6.11_12942.20141204_BTCOEX20140507-4E40" -#define BTCOEXVERSION "BTCOEX20140507-4E40" +#define DRIVERVERSION "v4.3.9.6_13610.20150310_BTCOEX20140929-5443" +#define BTCOEXVERSION "BTCOEX20140929-5443" diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_wifi_regd.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_wifi_regd.h index 8b28be34b0ae..aea6365290f8 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_wifi_regd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_wifi_regd.h @@ -19,10 +19,8 @@ enum country_code_type_t { COUNTRY_CODE_MAX }; -int rtw_regd_init(_adapter *padapter, - void (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)); -void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +int rtw_regd_init(_adapter *padapter); +void rtw_reg_notify_by_driver(_adapter *adapter); +#endif /* __RTW_WIFI_REGD_H__ */ -#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_xmit.h index 10bfb182a16f..d7d8fca072e2 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/rtw_xmit.h @@ -77,7 +77,12 @@ // xmit extension buff defination #define MAX_XMIT_EXTBUF_SZ (1536) + +#ifdef CONFIG_SINGLE_XMIT_BUF +#define NR_XMIT_EXTBUFF (1) +#else #define NR_XMIT_EXTBUFF (32) +#endif #define MAX_CMDBUF_SZ (5120) //(4096) @@ -158,7 +163,7 @@ do{\ #ifdef CONFIG_PCI_HCI #define TXDESC_SIZE ((TX_BUFFER_SEG_NUM ==0)?16: ((TX_BUFFER_SEG_NUM ==1)? 32:64) ) #define TX_WIFI_INFO_SIZE 40 - #else //USB or SDIO + #else //8192E USB or SDIO #define TXDESC_SIZE 40 #endif //8192EE_TODO @@ -193,6 +198,105 @@ do{\ #define TX_DESC_NEXT_DESC_OFFSET (TXDESC_SIZE + 8) #endif //CONFIG_PCI_HCI +#ifdef CONFIG_WOWLAN +// The following foramt is 40 bytes tx description. +// It supports 8192E, 8723B, 8812a. +// Dword 0 +#define GET_TX_DESC_OWN(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) +#define SET_TX_DESC_PKT_SIZE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) +// Dword 1 +#define SET_TX_DESC_MACID(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) +// Dword 2 +#define SET_TX_DESC_PAID(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_AGG_BREAK(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define SET_TX_DESC_RAW(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_INT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_MODE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) +// Dword 4 +#define SET_TX_DESC_TX_RATE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) +// Dword 5 +#define SET_TX_DESC_DATA_SC(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) +// Dword 6 +#define SET_TX_DESC_SW_DEFINE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_ANTSEL_A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 25, 3, __Value) +// Dword 7 +#ifdef CONFIG_PCI_HCI +#define SET_TX_DESC_TX_BUFFER_SIZE(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#else +#define SET_TX_DESC_TX_DESC_CHECKSUM(__pTxDesc, __Value)SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#endif +#define SET_TX_DESC_USB_TXAGG_NUM(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#define SET_TX_DESC_SDIO_TXSEQ(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 16, 8, __Value) +#endif + +// Dword 8 +#define SET_TX_DESC_HWSEQ_EN(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) +// Dword 9 +#define SET_TX_DESC_SEQ(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) +// Dword 10 +#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pTxDesc, __Value)SET_BITS_TO_LE_4BYTE(__pTxDesc+40, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+40, 0, 32) + +// Dword 11 +#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pTxDesc, __Value)SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 0, 32, __Value) +// 40 bytes tx description end. +#endif + enum TXDESC_SC{ SC_DONT_CARE = 0x00, SC_UPPER= 0x01, @@ -340,6 +444,7 @@ struct pkt_attrib u8 dhcp_pkt; u16 ether_type; u16 seqnum; + u8 hw_ssn_sel; //for HW_SEQ0,1,2,3 u16 pkt_hdrlen; //the original 802.3 pkt header len u16 hdrlen; //the WLAN Header Len u32 pktlen; //the original 802.3 pkt raw_data len (not include ether_hdr data) @@ -633,6 +738,8 @@ enum cmdbuf_type { CMDBUF_MAX }; +u8 rtw_get_hwseq_no(_adapter *padapter); + struct xmit_priv { _lock lock; @@ -744,7 +851,7 @@ struct xmit_priv { uint free_xmit_extbuf_cnt; struct xmit_buf pcmd_xmitbuf[CMDBUF_MAX]; - + u8 hw_ssn_seq_no;//mapping to REG_HW_SEQ 0,1,2,3 u16 nqos_ssn; #ifdef CONFIG_TX_EARLY_MODE diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/usb_ops_linux.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/usb_ops_linux.h index a048e83bda3d..83c1c74c2ce2 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/usb_ops_linux.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/usb_ops_linux.h @@ -65,5 +65,20 @@ u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); void usb_write_port_cancel(struct intf_hdl *pintfhdl); int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype); +#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ +int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, + u16 value, u16 index, void *pdata, u16 len, u8 requesttype); +#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */ + +u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr); +u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr); +u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr); +int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val); +int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val); +int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val); +int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata); +u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem); +void usb_recv_tasklet(void *priv); + #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/xmit_osdep.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/xmit_osdep.h index 79d0a8864bfe..d489ebfcf642 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/xmit_osdep.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/include/xmit_osdep.h @@ -92,5 +92,9 @@ extern sint rtw_endofpktfile (struct pkt_file *pfile); extern void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt); extern void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe); +void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed); + +void dump_os_queue(void *sel, _adapter *padapter); + #endif //__XMIT_OSDEP_H_ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_cfg80211.c index a0dedaf6152e..12ce112da794 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_cfg80211.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_cfg80211.c @@ -26,6 +26,7 @@ #include #define RTW_MAX_MGMT_TX_CNT (8) +#define RTW_MAX_MGMT_TX_MS_GAS (500) #define RTW_SCAN_IE_LEN_MAX 2304 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 //ms @@ -53,6 +54,12 @@ #endif +#ifdef CONFIG_PLATFORM_ARM_SUN8I +#define BUSY_TRAFFIC_SCAN_DENY_PERIOD 8000 +#else +#define BUSY_TRAFFIC_SCAN_DENY_PERIOD 12000 +#endif + static const u32 rtw_cipher_suites[] = { WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, @@ -377,7 +384,10 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_net u8 *notify_ie; size_t notify_ielen; s32 notify_signal; - u8 buf[MAX_BSSINFO_LEN], *pbuf; + //u8 buf[MAX_BSSINFO_LEN]; + + u8 *pbuf; + size_t buf_size = MAX_BSSINFO_LEN; size_t len,bssinf_len=0; struct rtw_ieee80211_hdr *pwlanhdr; unsigned short *fctrl; @@ -387,12 +397,17 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_net struct wiphy *wiphy = wdev->wiphy; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - + pbuf = rtw_zmalloc(buf_size); + if(pbuf == NULL){ + DBG_871X("%s pbuf allocate failed !! \n",__FUNCTION__); + return bss; + } + //DBG_8192C("%s\n", __func__); bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr); - if(bssinf_len > MAX_BSSINFO_LEN){ - DBG_871X("%s IE Length too long > %d byte \n",__FUNCTION__,MAX_BSSINFO_LEN); + if(bssinf_len > buf_size){ + DBG_871X("%s IE Length too long > %zu byte \n",__FUNCTION__,buf_size); goto exit; } @@ -522,7 +537,7 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_net DBG_8192C("notify_timestamp: %llu\n", notify_timestamp); #endif - pbuf = buf; + //pbuf = buf; pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf; fctrl = &(pwlanhdr->frame_ctl); @@ -543,13 +558,12 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_net _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN); - pbuf += sizeof(struct rtw_ieee80211_hdr_3addr); + //pbuf += sizeof(struct rtw_ieee80211_hdr_3addr); len = sizeof (struct rtw_ieee80211_hdr_3addr); - - _rtw_memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength); - len += pnetwork->network.IELength; - - *((u64*)pbuf) = cpu_to_le64(notify_timestamp); + _rtw_memcpy((pbuf+len), pnetwork->network.IEs, pnetwork->network.IELength); + *((u64*)(pbuf+len)) = cpu_to_le64(notify_timestamp); + + len += pnetwork->network.IELength; //#ifdef CONFIG_P2P //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL)) @@ -559,7 +573,7 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_net //#endif #if 1 - bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf, + bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf, len, notify_signal, GFP_ATOMIC); #else @@ -609,8 +623,10 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_net #else cfg80211_put_bss(bss); #endif - -exit: + +exit: + if(pbuf) + rtw_mfree(pbuf, buf_size); return bss; } @@ -657,6 +673,11 @@ void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter) struct wlan_network *cur_network = &(pmlmepriv->cur_network); struct wireless_dev *pwdev = padapter->rtw_wdev; struct cfg80211_bss *bss = NULL; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + struct wiphy *wiphy = pwdev->wiphy; + int freq = (int)cur_network->network.Configuration.DSConfig; + struct ieee80211_channel *chan; +#endif DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); if (pwdev->iftype != NL80211_IFTYPE_ADHOC) @@ -708,7 +729,12 @@ void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter) DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter)); } //notify cfg80211 that device joined an IBSS +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + chan = ieee80211_get_channel(wiphy, freq); + cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, chan, GFP_ATOMIC); +#else cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC); +#endif } void rtw_cfg80211_indicate_connect(_adapter *padapter) @@ -807,18 +833,18 @@ check_bss: } else { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE) + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE) DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state); -#endif // kernel < 3.11 + #endif cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6 , WLAN_STATUS_SUCCESS, GFP_ATOMIC); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE) + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE) DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state); -#endif // kernel < 3.11 + #endif } } @@ -857,7 +883,7 @@ void rtw_cfg80211_indicate_disconnect(_adapter *padapter) #endif //CONFIG_P2P if (!padapter->mlmepriv.not_indic_disco) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE) + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE) DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state); if(pwdev->sme_state==CFG80211_SME_CONNECTING) @@ -869,13 +895,14 @@ void rtw_cfg80211_indicate_disconnect(_adapter *padapter) //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state); DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state); -#else // kernel >= 3.11 - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) + #else + + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC); else - cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0, + cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/); -#endif // kernel >= 3.11 + #endif } } @@ -1545,13 +1572,13 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, if (params->seq_len && params->seq) { - _rtw_memcpy(param->u.crypt.seq, params->seq, params->seq_len); + _rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len); } if(params->key_len && params->key) { param->u.crypt.key_len = params->key_len; - _rtw_memcpy(param->u.crypt.key, params->key, params->key_len); + _rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len); } if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) @@ -1685,8 +1712,13 @@ static int cfg80211_rtw_set_default_key(struct wiphy *wiphy, } static int cfg80211_rtw_get_station(struct wiphy *wiphy, - struct net_device *ndev, - u8 *mac, struct station_info *sinfo) + struct net_device *ndev, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + u8 *mac, +#else + const u8 *mac, +#endif + struct station_info *sinfo) { int ret = 0; _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); @@ -1702,7 +1734,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy, goto exit; } - psta = rtw_get_stainfo(pstapriv, mac); + psta = rtw_get_stainfo(pstapriv, (u8 *)mac); if (psta == NULL) { DBG_8192C("%s, sta_info is null\n", __func__); ret = -ENOENT; @@ -1720,7 +1752,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy, { struct wlan_network *cur_network = &(pmlmepriv->cur_network); - if (_rtw_memcmp(mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) { + if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) { DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress)); ret = -ENOENT; goto exit; @@ -1993,7 +2025,16 @@ void rtw_cfg80211_surveydone_event_callback(_adapter *padapter) //ev=translate_scan(padapter, a, pnetwork, ev, stop); rtw_cfg80211_inform_bss(padapter, pnetwork); } - + /* //check ralink testbed RSN IE length + { + if(_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP",13)) + { + uint ie_len=0; + u8 *p=NULL; + p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_)); + DBG_871X("ie_len=%d\n", ie_len); + } + }*/ plist = get_next(plist); } @@ -2285,7 +2326,7 @@ if (padapter->registrypriv.mp_mode == 1) passtime = rtw_get_passing_time_ms(lastscantime); lastscantime = rtw_get_current_time(); - if (passtime > 12000) + if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) #endif { DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__); @@ -2309,7 +2350,7 @@ if (padapter->registrypriv.mp_mode == 1) passtime = rtw_get_passing_time_ms(buddylastscantime); buddylastscantime = rtw_get_current_time(); - if ((passtime > 12000) + if ((passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) //#ifdef CONFIG_P2P // ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) //#endif //CONFIG_P2P @@ -2896,7 +2937,7 @@ static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev, _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID)); ndis_ssid.SsidLength = params->ssid_len; - _rtw_memcpy(ndis_ssid.Ssid, params->ssid, params->ssid_len); + _rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len); //DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len); @@ -3041,7 +3082,7 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID)); ndis_ssid.SsidLength = sme->ssid_len; - _rtw_memcpy(ndis_ssid.Ssid, sme->ssid, sme->ssid_len); + _rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len); DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len); @@ -3095,7 +3136,7 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len); - ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len); + ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len); if (ret < 0) goto exit; @@ -3191,7 +3232,7 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); - if (rtw_set_802_11_connect(padapter, sme->bssid, &ndis_ssid) == _FALSE) { + if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) { ret = -1; goto exit; } @@ -3325,26 +3366,33 @@ static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, { u8 index,blInserted = _FALSE; _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *mlme = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 }; - DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev) + , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid)); - if ( _rtw_memcmp( pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE ) + if ( _rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE ) { return -EINVAL; } + if (check_fwstate(mlme, _FW_LINKED) == _FALSE) { + DBG_871X(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev)); + return -EINVAL; + } + blInserted = _FALSE; //overwrite PMKID for(index=0 ; indexPMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE ) + if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE ) { // BSSID is matched, the same AP => rewrite with new PMKID. DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev)); - _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN); + _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN); psecuritypriv->PMKIDList[index].bUsed = _TRUE; psecuritypriv->PMKIDIndex = index+1; blInserted = _TRUE; @@ -3358,8 +3406,8 @@ static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n", FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex ); - _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, pmksa->bssid, ETH_ALEN); - _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmksa->pmkid, WLAN_PMKID_LEN); + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN); + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN); psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE; psecuritypriv->PMKIDIndex++ ; @@ -3380,16 +3428,18 @@ static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy, _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); struct security_priv *psecuritypriv = &padapter->securitypriv; - DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev) + , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid)); for(index=0 ; indexPMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE ) + if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE ) { // BSSID is matched, the same AP => Remove this PMKID information and reset it. - _rtw_memset( psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN ); - _rtw_memset( psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN ); + _rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN ); + _rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN ); psecuritypriv->PMKIDList[index].bUsed = _FALSE; bMatched = _TRUE; + DBG_871X(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index); break; } } @@ -4114,7 +4164,12 @@ static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev) #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev, - u8 *mac, struct station_parameters *params) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + u8 *mac, +#else + const u8 *mac, +#endif + struct station_parameters *params) { DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); @@ -4122,7 +4177,12 @@ static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev } static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev, - u8 *mac) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + u8 *mac +#else + const u8 *mac +#endif + ) { int ret=0; _irqL irqL; @@ -4176,7 +4236,7 @@ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev plist = get_next(plist); - if(_rtw_memcmp(mac, psta->hwaddr, ETH_ALEN)) + if(_rtw_memcmp((u8 *)mac, psta->hwaddr, ETH_ALEN)) { if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE) { @@ -4190,7 +4250,10 @@ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev pstapriv->asoc_list_cnt--; //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); - updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING); + if (check_fwstate(pmlmepriv, (WIFI_AP_STATE)) == _TRUE) + updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID); + else + updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING); //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); psta = NULL; @@ -4213,7 +4276,12 @@ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev } static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev, - u8 *mac, struct station_parameters *params) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + u8 *mac, +#else + const u8 *mac, +#endif + struct station_parameters *params) { DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); @@ -4222,7 +4290,7 @@ static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *n struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv) -{ +{ _list *phead, *plist; struct sta_info *psta = NULL; int i = 0; @@ -4406,11 +4474,14 @@ void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const rtw_action_frame_parse(frame, frame_len, &category, &action); - DBG_8192C("RTW_Rx:cur_ch=%d\n", channel); - if (msg) - DBG_871X("RTW_Rx:%s\n", msg); - else - DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action); + if (action == ACT_PUBLIC_GAS_INITIAL_REQ) { + rtw_set_scan_deny(adapter, 200); + rtw_scan_abort_no_wait(adapter); + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(adapter)) + rtw_scan_abort_no_wait(adapter->pbuddy_adapter); + #endif + } if (channel <= RTW_CH_MAX_2G_CHANNEL) freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); @@ -4423,6 +4494,11 @@ void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC); #endif + DBG_8192C("RTW_Rx:cur_ch=%d\n", channel); + if (msg) + DBG_871X("RTW_Rx:%s\n", msg); + else + DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action); } #ifdef CONFIG_P2P @@ -4674,6 +4750,13 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, struct mlme_ext_priv *pmlmeext; struct wifidirect_info *pwdinfo; struct cfg80211_wifidirect_info *pcfg80211_wdinfo; + u8 is_p2p_find = _FALSE; + + +#ifndef CONFIG_RADIO_WORK + #define RTW_ROCH_DURATION_ENLARGE + #define RTW_ROCH_BACK_OP +#endif if (ndev == NULL) { return -EINVAL; @@ -4684,19 +4767,20 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, pmlmeext = &padapter->mlmeextpriv; pwdinfo = &padapter->wdinfo; pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + #ifdef CONFIG_CONCURRENT_MODE + is_p2p_find=(duration < (pwdinfo->ext_listen_interval))? _TRUE : _FALSE; + #endif + *cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen); - DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration); + DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), remain_ch, duration, *cookie); if(pcfg80211_wdinfo->is_ro_ch == _TRUE) { DBG_8192C("%s, cancel ro ch timer\n", __func__); - _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); - -#ifdef CONFIG_CONCURRENT_MODE - ATOMIC_SET(&pwdev_priv->ro_ch_to, 1); -#endif //CONFIG_CONCURRENT_MODE - + #ifdef CONFIG_CONCURRENT_MODE + ATOMIC_SET(&pwdev_priv->ro_ch_to, 1); + #endif //CONFIG_CONCURRENT_MODE p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK); } @@ -4716,7 +4800,7 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, rtw_scan_abort(padapter); #ifdef CONFIG_CONCURRENT_MODE - if(rtw_buddy_adapter_up(padapter)) + if ((rtw_buddy_adapter_up(padapter)) && is_p2p_find) //don't scan_abort during p2p_listen. rtw_scan_abort(padapter->pbuddy_adapter); #endif //CONFIG_CONCURRENT_MODE @@ -4751,18 +4835,23 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); - +#ifdef RTW_ROCH_DURATION_ENLARGE if(duration < 400) duration = duration*3;//extend from exper. +#endif /* RTW_ROCH_DURATION_ENLARGE */ - +#ifdef RTW_ROCH_BACK_OP #ifdef CONFIG_CONCURRENT_MODE - if(check_buddy_fwstate(padapter, _FW_LINKED) && - (durationext_listen_interval)) + if (check_buddy_fwstate(padapter, _FW_LINKED)) { - duration = duration + pwdinfo->ext_listen_interval; + if (is_p2p_find) // p2p_find , duration<1000 + duration = duration + pwdinfo->ext_listen_interval; + else // p2p_listen, duration=5000 + duration = pwdinfo->ext_listen_interval + + (pwdinfo->ext_listen_interval/4); } #endif +#endif /* RTW_ROCH_BACK_OP */ pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter); @@ -4782,9 +4871,11 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500); ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); - + + #ifdef RTW_ROCH_BACK_OP DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval); - _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval); + _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval); + #endif /* RTW_ROCH_BACK_OP */ } } @@ -4875,7 +4966,7 @@ static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy, pwdinfo = &padapter->wdinfo; pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; - DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + DBG_871X(FUNC_ADPT_FMT" cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), cookie); if (pcfg80211_wdinfo->is_ro_ch == _TRUE) { DBG_8192C("%s, cancel ro ch timer\n", __func__); @@ -5082,33 +5173,33 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE) struct ieee80211_channel *chan, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) bool offchan, -#endif // kernel >= 2.6.38 -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + #endif + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) enum nl80211_channel_type channel_type, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) bool channel_type_valid, -#endif // kernel >= 2.6.37 -#endif // kernel < 3.8 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + #endif + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) unsigned int wait, -#endif // kernel >= 2.6.38 + #endif const u8 *buf, size_t len, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) bool no_cck, -#endif // kernel >= 3.2 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) bool dont_wait_for_ack, -#endif // kernel >= 3.3 -#else // kernel >= 3.14 + #endif +#else struct cfg80211_mgmt_tx_params *params, -#endif // kernel >= 3.14 +#endif u64 *cookie) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) struct net_device *ndev = wdev_to_ndev(wdev); -#endif // kernel >= 3.6 +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE) struct ieee80211_channel *chan = params->chan; bool offchan = params->offchan; @@ -5117,7 +5208,7 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, size_t len = params->len; bool no_cck = params->no_cck; bool dont_wait_for_ack = params->dont_wait_for_ack; -#endif // kernel >= 3.14 +#endif int ret = 0; int tx_ret; u32 dump_limit = RTW_MAX_MGMT_TX_CNT; @@ -5192,10 +5283,27 @@ dump: goto cancel_ps_deny; } - do { + while (1) { + u32 sleep_ms = 0; + u32 retry_guarantee_ms = 0; + dump_cnt++; tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len); - } while (dump_cnt < dump_limit && tx_ret != _SUCCESS); + + switch (action) { + case ACT_PUBLIC_GAS_INITIAL_REQ: + case ACT_PUBLIC_GAS_INITIAL_RSP: + sleep_ms = 50; + retry_guarantee_ms = RTW_MAX_MGMT_TX_MS_GAS; + } + + if (tx_ret == _SUCCESS + || (dump_cnt >= dump_limit && rtw_get_passing_time_ms(start) >= retry_guarantee_ms)) + break; + + if (sleep_ms > 0) + rtw_msleep_os(sleep_ms); + } if (tx_ret != _SUCCESS || dump_cnt > 1) { DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter), @@ -5898,7 +6006,7 @@ void rtw_cfg80211_init_wiphy(_adapter *padapter) } /* init regulary domain */ - rtw_regd_init(padapter, rtw_reg_notifier); + rtw_regd_init(padapter); /* copy mac_addr to wiphy */ _rtw_memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); @@ -5945,7 +6053,9 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy) | BIT(NL80211_IFTYPE_ADHOC) #ifdef CONFIG_AP_MODE | BIT(NL80211_IFTYPE_AP) +#ifndef CONFIG_RADIO_WORK | BIT(NL80211_IFTYPE_MONITOR) +#endif /* !CONFIG_RADIO_WORK */ #endif #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) | BIT(NL80211_IFTYPE_P2P_CLIENT) @@ -5960,7 +6070,9 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy) #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#ifndef CONFIG_RADIO_WORK wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); +#endif /* !CONFIG_RADIO_WORK */ #endif /* @@ -5995,10 +6107,10 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy) #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)) wiphy->wowlan = wowlan_stub; -#else // kernel >= 3.11 +#else wiphy->wowlan = &wowlan_stub; -#endif // kernel >= 3.11 -#endif // kernle >= 3.0 +#endif +#endif #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; @@ -6013,6 +6125,10 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) //wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; #endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) + rtw_cfgvendor_attach(wiphy); +#endif } static struct cfg80211_ops rtw_cfg80211_ops = { @@ -6205,6 +6321,10 @@ void rtw_wdev_unregister(struct wireless_dev *wdev) unregister_netdev(pwdev_priv->pmon_ndev); } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) + rtw_cfgvendor_detach(wdev->wiphy); +#endif + wiphy_unregister(wdev->wiphy); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_cfg80211.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_cfg80211.h new file mode 100755 index 000000000000..3727922c43ba --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_cfg80211.h @@ -0,0 +1,179 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __IOCTL_CFG80211_H__ +#define __IOCTL_CFG80211_H__ + + +#if defined(RTW_USE_CFG80211_STA_EVENT) + #undef CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER +#endif + +struct rtw_wdev_invit_info { + u8 state; /* 0: req, 1:rep */ + u8 peer_mac[ETH_ALEN]; + u8 active; + u8 token; + u8 flags; + u8 status; + u8 req_op_ch; + u8 rsp_op_ch; +}; + +#define rtw_wdev_invit_info_init(invit_info) \ + do { \ + (invit_info)->state = 0xff; \ + _rtw_memset((invit_info)->peer_mac, 0, ETH_ALEN); \ + (invit_info)->active = 0xff; \ + (invit_info)->token = 0; \ + (invit_info)->flags = 0x00; \ + (invit_info)->status = 0xff; \ + (invit_info)->req_op_ch = 0; \ + (invit_info)->rsp_op_ch = 0; \ + } while (0) + +struct rtw_wdev_nego_info { + u8 state; /* 0: req, 1:rep, 2:conf */ + u8 peer_mac[ETH_ALEN]; + u8 active; + u8 token; + u8 status; + u8 req_intent; + u8 req_op_ch; + u8 req_listen_ch; + u8 rsp_intent; + u8 rsp_op_ch; + u8 conf_op_ch; +}; + +#define rtw_wdev_nego_info_init(nego_info) \ + do { \ + (nego_info)->state = 0xff; \ + _rtw_memset((nego_info)->peer_mac, 0, ETH_ALEN); \ + (nego_info)->active = 0xff; \ + (nego_info)->token = 0; \ + (nego_info)->status = 0xff; \ + (nego_info)->req_intent = 0xff; \ + (nego_info)->req_op_ch = 0; \ + (nego_info)->req_listen_ch = 0; \ + (nego_info)->rsp_intent = 0xff; \ + (nego_info)->rsp_op_ch = 0; \ + (nego_info)->conf_op_ch = 0; \ + } while (0) + +struct rtw_wdev_priv +{ + struct wireless_dev *rtw_wdev; + + _adapter *padapter; + + struct cfg80211_scan_request *scan_request; + _lock scan_req_lock; + + struct net_device *pmon_ndev;//for monitor interface + char ifname_mon[IFNAMSIZ + 1]; //interface name for monitor interface + + u8 p2p_enabled; + + u8 provdisc_req_issued; + + struct rtw_wdev_invit_info invit_info; + struct rtw_wdev_nego_info nego_info; + + u8 bandroid_scan; + bool block; + bool power_mgmt; + +#ifdef CONFIG_CONCURRENT_MODE + ATOMIC_T ro_ch_to; + ATOMIC_T switch_ch_to; +#endif + +}; + +#define wiphy_to_adapter(x) (*((_adapter**)wiphy_priv(x))) + +#define wdev_to_ndev(w) ((w)->netdev) + +int rtw_wdev_alloc(_adapter *padapter, struct device *dev); +void rtw_wdev_free(struct wireless_dev *wdev); +void rtw_wdev_unregister(struct wireless_dev *wdev); + +void rtw_cfg80211_init_wiphy(_adapter *padapter); + +void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork); +void rtw_cfg80211_surveydone_event_callback(_adapter *padapter); +struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork); +int rtw_cfg80211_check_bss(_adapter *padapter); +void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter); +void rtw_cfg80211_indicate_connect(_adapter *padapter); +void rtw_cfg80211_indicate_disconnect(_adapter *padapter); +void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted); + +#ifdef CONFIG_AP_MODE +void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len); +void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason); +#endif //CONFIG_AP_MODE + +void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len); +void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len); +void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len); +void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg); + +int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, int type); + +bool rtw_cfg80211_pwr_mgmt(_adapter *adapter); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE) +#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->pnetdev, freq, buf, len, gfp) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) +#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->pnetdev, freq, sig_dbm, buf, len, gfp) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)) +#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->rtw_wdev, freq, sig_dbm, buf, len, gfp) +#else +#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->rtw_wdev, freq, sig_dbm, buf, len,0,gfp) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE) +#define rtw_cfg80211_send_rx_assoc(adapter, bss, buf, len) cfg80211_send_rx_assoc((adapter)->pnetdev, buf, len) +#else +#define rtw_cfg80211_send_rx_assoc(adapter, bss, buf, len) cfg80211_send_rx_assoc((adapter)->pnetdev, bss, buf, len) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) +#define rtw_cfg80211_mgmt_tx_status(adapter, cookie, buf, len, ack, gfp) cfg80211_mgmt_tx_status((adapter)->pnetdev, cookie, buf, len, ack, gfp) +#else +#define rtw_cfg80211_mgmt_tx_status(adapter, cookie, buf, len, ack, gfp) cfg80211_mgmt_tx_status((adapter)->rtw_wdev, cookie, buf, len, ack, gfp) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) +#define rtw_cfg80211_ready_on_channel(adapter, cookie, chan, channel_type, duration, gfp) cfg80211_ready_on_channel((adapter)->pnetdev, cookie, chan, channel_type, duration, gfp) +#define rtw_cfg80211_remain_on_channel_expired(adapter, cookie, chan, chan_type, gfp) cfg80211_remain_on_channel_expired((adapter)->pnetdev, cookie, chan, chan_type, gfp) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) +#define rtw_cfg80211_ready_on_channel(adapter, cookie, chan, channel_type, duration, gfp) cfg80211_ready_on_channel((adapter)->rtw_wdev, cookie, chan, channel_type, duration, gfp) +#define rtw_cfg80211_remain_on_channel_expired(adapter, cookie, chan, chan_type, gfp) cfg80211_remain_on_channel_expired((adapter)->rtw_wdev, cookie, chan, chan_type, gfp) +#else +#define rtw_cfg80211_ready_on_channel(adapter, cookie, chan, channel_type, duration, gfp) cfg80211_ready_on_channel((adapter)->rtw_wdev, cookie, chan, duration, gfp) +#define rtw_cfg80211_remain_on_channel_expired(adapter, cookie, chan, chan_type, gfp) cfg80211_remain_on_channel_expired((adapter)->rtw_wdev, cookie, chan, gfp) +#endif + +#include "rtw_cfgvendor.h" + +#endif //__IOCTL_CFG80211_H__ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_linux.c index 6124cb80b901..1c6c50b91555 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/ioctl_linux.c @@ -23,7 +23,7 @@ //#ifdef CONFIG_MP_INCLUDED #include -#include "../../hal/OUTSRC/odm_precomp.h" +#include "../../hal/OUTSRC/phydm_precomp.h" //#endif #if defined(CONFIG_RTL8723A) @@ -304,28 +304,12 @@ uint rtw_is_cckratesonly_included(u8 *rate) } */ -static char *translate_scan(_adapter *padapter, +static int search_p2p_wfd_ie(_adapter *padapter, struct iw_request_info* info, struct wlan_network *pnetwork, char *start, char *stop) { - struct iw_event iwe; - u16 cap; - u32 ht_ielen = 0, vht_ielen = 0; - char custom[MAX_CUSTOM_LEN]; - char *p; - u16 max_rate=0, rate, ht_cap=_FALSE, vht_cap = _FALSE; - u32 i = 0; - char *current_val; - long rssi; - u8 bw_40MHz=0, short_GI=0, bw_160MHz=0, vht_highest_rate = 0; - u16 mcs_rate=0, vht_data_rate=0; - u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12); - struct registry_priv *pregpriv = &padapter->registrypriv; #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &padapter->wdinfo; -#endif //CONFIG_P2P - -#ifdef CONFIG_P2P #ifdef CONFIG_WFD if ( SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type ) { @@ -357,7 +341,7 @@ static char *translate_scan(_adapter *padapter, if ( blnGotP2PIE == _FALSE ) { - return start; + return _FALSE; } } @@ -401,12 +385,547 @@ static char *translate_scan(_adapter *padapter, if ( blnGotWFD == _FALSE ) { - return start; + return _FALSE; } } #endif // CONFIG_WFD #endif //CONFIG_P2P + return _TRUE; +} + static inline char *iwe_stream_mac_addr_proess(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + /* AP MAC address */ + iwe->cmd = SIOCGIWAP; + iwe->u.ap_addr.sa_family = ARPHRD_ETHER; + + _rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN); + start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN); + return start; +} + static inline char * iwe_stream_essid_proess(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + + /* Add the ESSID */ + iwe->cmd = SIOCGIWESSID; + iwe->u.data.flags = 1; + iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32); + start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid); + return start; +} + + static inline char * iwe_stream_chan_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + if(pnetwork->network.Configuration.DSConfig<1 /*|| pnetwork->network.Configuration.DSConfig>14*/) + pnetwork->network.Configuration.DSConfig = 1; + + /* Add frequency/channel */ + iwe->cmd = SIOCGIWFREQ; + iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000; + iwe->u.freq.e = 1; + iwe->u.freq.i = pnetwork->network.Configuration.DSConfig; + start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN); + return start; +} + static inline char * iwe_stream_mode_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe,u16 cap) +{ + /* Add mode */ + if(cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)){ + iwe->cmd = SIOCGIWMODE; + if (cap & WLAN_CAPABILITY_BSS) + iwe->u.mode = IW_MODE_MASTER; + else + iwe->u.mode = IW_MODE_ADHOC; + + start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN); + } + return start; + } + static inline char * iwe_stream_encryption_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe,u16 cap) +{ + + /* Add encryption capability */ + iwe->cmd = SIOCGIWENCODE; + if (cap & WLAN_CAPABILITY_PRIVACY) + iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe->u.data.flags = IW_ENCODE_DISABLED; + iwe->u.data.length = 0; + start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid); + return start; + +} + + static inline char * iwe_stream_protocol_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) + { + u16 ht_cap=_FALSE,vht_cap = _FALSE; + u32 ht_ielen = 0, vht_ielen = 0; + char *p; + u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);// Probe Request + + //parsing HT_CAP_IE + p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-ie_offset); + if(p && ht_ielen>0) + ht_cap = _TRUE; + + #ifdef CONFIG_80211AC_VHT + //parsing VHT_CAP_IE + p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset); + if(p && vht_ielen>0) + vht_cap = _TRUE; + #endif + /* Add the protocol name */ + iwe->cmd = SIOCGIWNAME; + if ((rtw_is_cckratesonly_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE) + { + if(ht_cap == _TRUE) + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn"); + else + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b"); + } + else if ((rtw_is_cckrates_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE) + { + if(ht_cap == _TRUE) + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn"); + else + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg"); + } + else + { + if(pnetwork->network.Configuration.DSConfig > 14) + { + #ifdef CONFIG_80211AC_VHT + if(vht_cap == _TRUE){ + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC"); + } + else + #endif + { + if(ht_cap == _TRUE) + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an"); + else + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a"); + } + } + else + { + if(ht_cap == _TRUE) + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn"); + else + snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g"); + } + } + start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN); + return start; + } + + static inline char * iwe_stream_rate_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + u32 ht_ielen = 0, vht_ielen = 0; + char *p; + u16 max_rate=0, rate, ht_cap=_FALSE, vht_cap = _FALSE; + u32 i = 0; + u8 bw_40MHz=0, short_GI=0, bw_160MHz=0, vht_highest_rate = 0; + u16 mcs_rate=0, vht_data_rate=0; + char custom[MAX_CUSTOM_LEN]={0}; + u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);// Probe Request + + //parsing HT_CAP_IE + p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-ie_offset); + if(p && ht_ielen>0) + { + struct rtw_ieee80211_ht_cap *pht_capie; + ht_cap = _TRUE; + pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2); + _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2); + bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1:0; + short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0; + } + +#ifdef CONFIG_80211AC_VHT + //parsing VHT_CAP_IE + p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset); + if(p && vht_ielen>0) + { + u8 mcs_map[2]; + + vht_cap = _TRUE; + bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2); + if(bw_160MHz) + short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p+2); + else + short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p+2); + + _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p+2), 2); + + vht_highest_rate = rtw_get_vht_highest_rate(mcs_map); + vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate); + } +#endif + + /*Add basic and extended rates */ + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); + while(pnetwork->network.SupportedRates[i]!=0) + { + rate = pnetwork->network.SupportedRates[i]&0x7F; + if (rate > max_rate) + max_rate = rate; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); + i++; + } +#ifdef CONFIG_80211AC_VHT + if(vht_cap == _TRUE) { + max_rate = vht_data_rate; + } + else +#endif + if(ht_cap == _TRUE) + { + if(mcs_rate&0x8000)//MCS15 + { + max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); + + } + else if(mcs_rate&0x0080)//MCS7 + { + max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); + } + else//default MCS7 + { + //DBG_871X("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate); + max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); + } + + max_rate = max_rate*2;//Mbps/2; + } + + iwe->cmd = SIOCGIWRATE; + iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0; + iwe->u.bitrate.value = max_rate * 500000; + start =iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN); + return start ; +} + +static inline char * iwe_stream_wpa_wpa2_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + int buf_size = MAX_WPA_IE_LEN*2; + //u8 pbuf[buf_size]={0}; + u8 *pbuf = rtw_zmalloc(buf_size); + + u8 wpa_ie[255]={0},rsn_ie[255]={0}; + u16 i, wpa_len=0,rsn_len=0; + u8 *p; + sint out_len=0; + + + if(pbuf){ + p=pbuf; + + //parsing WPA/WPA2 IE + if (pnetwork->network.Reserved[0] != 2) // Probe Request + { + out_len=rtw_get_sec_ie(pnetwork->network.IEs ,pnetwork->network.IELength,rsn_ie,&rsn_len,wpa_ie,&wpa_len); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len)); + + if (wpa_len > 0){ + + _rtw_memset(pbuf, 0, buf_size); + p += sprintf(p, "wpa_ie="); + for (i = 0; i < wpa_len; i++) { + p += sprintf(p, "%02x", wpa_ie[i]); + } + + if (wpa_len > 100) { + printk("-----------------Len %d----------------\n", wpa_len); + for (i = 0; i < wpa_len; i++) { + printk("%02x ", wpa_ie[i]); + } + printk("\n"); + printk("-----------------Len %d----------------\n", wpa_len); + } + + _rtw_memset(iwe, 0, sizeof(*iwe)); + iwe->cmd = IWEVCUSTOM; + iwe->u.data.length = strlen(pbuf); + start = iwe_stream_add_point(info, start, stop, iwe,pbuf); + + _rtw_memset(iwe, 0, sizeof(*iwe)); + iwe->cmd =IWEVGENIE; + iwe->u.data.length = wpa_len; + start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie); + } + if (rsn_len > 0){ + + _rtw_memset(pbuf, 0, buf_size); + p += sprintf(p, "rsn_ie="); + for (i = 0; i < rsn_len; i++) { + p += sprintf(p, "%02x", rsn_ie[i]); + } + _rtw_memset(iwe, 0, sizeof(*iwe)); + iwe->cmd = IWEVCUSTOM; + iwe->u.data.length = strlen(pbuf); + start = iwe_stream_add_point(info, start, stop, iwe,pbuf); + + _rtw_memset(iwe, 0, sizeof(*iwe)); + iwe->cmd =IWEVGENIE; + iwe->u.data.length = rsn_len; + start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie); + } + } + + rtw_mfree(pbuf, buf_size); + } + return start; +} + +static inline char * iwe_stream_wps_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + //parsing WPS IE + uint cnt = 0,total_ielen; + u8 *wpsie_ptr=NULL; + uint wps_ielen = 0; + u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12); + + u8 *ie_ptr = pnetwork->network.IEs + ie_offset; + total_ielen= pnetwork->network.IELength - ie_offset; + + if (pnetwork->network.Reserved[0] == 2) // Probe Request + { + ie_ptr = pnetwork->network.IEs; + total_ielen = pnetwork->network.IELength; + } + else // Beacon or Probe Respones + { + ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_; + total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; + } + while(cnt < total_ielen) + { + if(rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2)) + { + wpsie_ptr = &ie_ptr[cnt]; + iwe->cmd =IWEVGENIE; + iwe->u.data.length = (u16)wps_ielen; + start = iwe_stream_add_point(info, start, stop,iwe, wpsie_ptr); + } + cnt+=ie_ptr[cnt+1]+2; //goto next + } + return start; +} + +static inline char * iwe_stream_wapi_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ +#ifdef CONFIG_WAPI_SUPPORT + char *p; + + if (pnetwork->network.Reserved[0] != 2) // Probe Request + { + sint out_len_wapi=0; + /* here use static for stack size */ + static u8 buf_wapi[MAX_WAPI_IE_LEN*2]={0}; + static u8 wapi_ie[MAX_WAPI_IE_LEN]={0}; + u16 wapi_len=0; + u16 i; + + out_len_wapi=rtw_get_wapi_ie(pnetwork->network.IEs ,pnetwork->network.IELength,wapi_ie,&wapi_len); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wapi_len=%d \n",wapi_len)); + + DBG_871X("rtw_wx_get_scan: %s ",pnetwork->network.Ssid.Ssid); + DBG_871X("rtw_wx_get_scan: ssid = %d ",wapi_len); + + + if (wapi_len > 0) + { + p=buf_wapi; + //_rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2); + p += sprintf(p, "wapi_ie="); + for (i = 0; i < wapi_len; i++) { + p += sprintf(p, "%02x", wapi_ie[i]); + } + + _rtw_memset(iwe, 0, sizeof(*iwe)); + iwe->cmd = IWEVCUSTOM; + iwe->u.data.length = strlen(buf_wapi); + start = iwe_stream_add_point(info, start, stop, iwe,buf_wapi); + + _rtw_memset(iwe, 0, sizeof(*iwe)); + iwe->cmd =IWEVGENIE; + iwe->u.data.length = wapi_len; + start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie); + } + } +#endif//#ifdef CONFIG_WAPI_SUPPORT + return start; +} + +static inline char * iwe_stream_rssi_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + u8 ss, sq; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + /* Add quality statistics */ + iwe->cmd = IWEVQUAL; + iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED + #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) + | IW_QUAL_NOISE_UPDATED + #else + | IW_QUAL_NOISE_INVALID + #endif + #ifdef CONFIG_SIGNAL_DISPLAY_DBM + | IW_QUAL_DBM + #endif + ; + + if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE && + is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)){ + ss = padapter->recvpriv.signal_strength; + sq = padapter->recvpriv.signal_qual; + } else { + ss = pnetwork->network.PhyInfo.SignalStrength; + sq = pnetwork->network.PhyInfo.SignalQuality; + } + + + #ifdef CONFIG_SIGNAL_DISPLAY_DBM + iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss);//dbm + #else + #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING + { + /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */ + + HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter); + + iwe->u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss); + } + #else + iwe->u.qual.level = (u8)ss;//% + #endif + #endif + + iwe->u.qual.qual = (u8)sq; // signal quality + + #ifdef CONFIG_PLATFORM_ROCKCHIPS + iwe->u.qual.noise = -100; // noise level suggest by zhf@rockchips + #else + #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) + { + s16 tmp_noise=0; + rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(tmp_noise)); + iwe->u.qual.noise = tmp_noise ; + } + #else + iwe->u.qual.noise = 0; // noise level + #endif + #endif //CONFIG_PLATFORM_ROCKCHIPS + + //DBG_871X("iqual=%d, ilevel=%d, inoise=%d, iupdated=%d\n", iwe.u.qual.qual, iwe.u.qual.level , iwe.u.qual.noise, iwe.u.qual.updated); + + start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN); + return start; +} + +static inline char * iwe_stream_net_rsv_process(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop,struct iw_event *iwe) +{ + u8 buf[32] = {0}; + u8 * p,*pos; + int len; + p = buf; + pos = pnetwork->network.Reserved; + + p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]); + _rtw_memset(iwe, 0, sizeof(*iwe)); + iwe->cmd = IWEVCUSTOM; + iwe->u.data.length = strlen(buf); + start = iwe_stream_add_point(info, start, stop,iwe, buf); + return start; +} + +#if 1 +static char *translate_scan(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop) +{ + struct iw_event iwe; + u16 cap = 0; + _rtw_memset(&iwe, 0, sizeof(iwe)); + + if(_FALSE == search_p2p_wfd_ie(padapter,info,pnetwork,start,stop)) + return start; + + start = iwe_stream_mac_addr_proess(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_essid_proess(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_protocol_process(padapter,info,pnetwork,start,stop,&iwe); + if (pnetwork->network.Reserved[0] == 2) // Probe Request + { + cap = 0; + } + else + { + _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); + cap = le16_to_cpu(cap); + } + + start = iwe_stream_mode_process(padapter,info,pnetwork,start,stop,&iwe,cap); + start = iwe_stream_chan_process(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_encryption_process(padapter,info,pnetwork,start,stop,&iwe,cap); + start = iwe_stream_rate_process(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_wpa_wpa2_process(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_wps_process(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_wapi_process(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_rssi_process(padapter,info,pnetwork,start,stop,&iwe); + start = iwe_stream_net_rsv_process(padapter,info,pnetwork,start,stop,&iwe); + + return start; +} +#else +static char *translate_scan(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop) +{ + struct iw_event iwe; + u16 cap; + u32 ht_ielen = 0, vht_ielen = 0; + char custom[MAX_CUSTOM_LEN]; + char *p; + u16 max_rate=0, rate, ht_cap=_FALSE, vht_cap = _FALSE; + u32 i = 0; + char *current_val; + long rssi; + u8 bw_40MHz=0, short_GI=0, bw_160MHz=0, vht_highest_rate = 0; + u16 mcs_rate=0, vht_data_rate=0; + u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12); + struct registry_priv *pregpriv = &padapter->registrypriv; + + if(_FALSE == search_p2p_wfd_ie(padapter,info,pnetwork,start,stop)) + return start; /* AP MAC address */ iwe.cmd = SIOCGIWAP; @@ -414,7 +933,7 @@ static char *translate_scan(_adapter *padapter, _rtw_memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN); start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); - + /* Add the ESSID */ iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; @@ -796,6 +1315,7 @@ static char *translate_scan(_adapter *padapter, return start; } +#endif static int wpa_set_auth_algs(struct net_device *dev, u32 value) { @@ -1404,12 +1924,18 @@ static int rtw_wx_get_name(struct net_device *dev, { if(pcur_bss->Configuration.DSConfig > 14) { - if(vht_cap == _TRUE) + #ifdef CONFIG_80211AC_VHT + if(vht_cap == _TRUE){ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC"); - else if(ht_cap == _TRUE) - snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an"); + } else - snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a"); + #endif + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a"); + } } else { @@ -6675,6 +7201,10 @@ exit: #ifdef CONFIG_IOL #include #endif + +#ifdef DBG_CMD_QUEUE +u8 dump_cmd_id=0; +#endif static int rtw_dbg_port(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -7047,7 +7577,7 @@ static int rtw_dbg_port(struct net_device *dev, pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt, precvpriv->free_recvframe_cnt); #ifdef CONFIG_USB_HCI - DBG_871X("rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt); + DBG_871X("rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt))); #endif } break; @@ -7176,7 +7706,7 @@ static int rtw_dbg_port(struct net_device *dev, DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg); - if((extra_arg & 0x03) > 0x03) + if(extra_arg > 0x03) padapter->driver_rx_ampdu_factor = 0xFF; else padapter->driver_rx_ampdu_factor = extra_arg; @@ -7211,7 +7741,22 @@ static int rtw_dbg_port(struct net_device *dev, break; case 0x11://dump linked status { - linked_info_dump(padapter,extra_arg); + int pre_mode; + pre_mode=padapter->bLinkInfoDump; + // linked_info_dump(padapter,extra_arg); + if(extra_arg==1 || (extra_arg==0 && pre_mode==1) ) //not consider pwr_saving 0: + { + padapter->bLinkInfoDump = extra_arg; + + } + else if( (extra_arg==2 ) || (extra_arg==0 && pre_mode==2))//consider power_saving + { + //DBG_871X("linked_info_dump =%s \n", (padapter->bLinkInfoDump)?"enable":"disable") + linked_info_dump(padapter,extra_arg); + } + + + } break; #ifdef CONFIG_80211N_HT @@ -7369,7 +7914,7 @@ static int rtw_dbg_port(struct net_device *dev, DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg); - if((extra_arg & 0x07) > 0x07) + if(extra_arg > 0x07) padapter->driver_ampdu_spacing = 0xFF; else padapter->driver_ampdu_spacing = extra_arg; @@ -7414,9 +7959,9 @@ static int rtw_dbg_port(struct net_device *dev, * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7 */ - int value; + u8 value; DBG_871X("Read GPIO Value extra_arg = %d\n",extra_arg); - value = rtw_get_gpio(dev,extra_arg); + value = rtw_hal_get_gpio(padapter,extra_arg); DBG_871X("Read GPIO Value = %d\n",value); break; } @@ -7429,7 +7974,7 @@ static int rtw_dbg_port(struct net_device *dev, int value; DBG_871X("Set GPIO Direction! arg = %d ,extra_arg=%d\n",arg ,extra_arg); - value = rtw_config_gpio(dev, arg, extra_arg); + value = rtw_hal_config_gpio(padapter, arg, extra_arg); DBG_871X("Set GPIO Direction %s \n",(value==-1)?"Fail!!!":"Success"); break; } @@ -7442,11 +7987,19 @@ static int rtw_dbg_port(struct net_device *dev, int value; DBG_871X("Set GPIO Value! arg = %d ,extra_arg=%d\n",arg ,extra_arg); - value = rtw_set_gpio_output_value(dev,arg,extra_arg); + value = rtw_hal_set_gpio_output_value(padapter,arg,extra_arg); DBG_871X("Set GPIO Value %s \n",(value==-1)?"Fail!!!":"Success"); break; } -#endif +#endif +#ifdef DBG_CMD_QUEUE + case 0x28: + { + dump_cmd_id = extra_arg; + DBG_871X("dump_cmd_id:%d\n",dump_cmd_id); + } + break; +#endif //DBG_CMD_QUEUE case 0xaa: { if((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF; @@ -8165,9 +8718,9 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) if(psta) { DBG_871X("rtw_add_sta(), free has been added psta=%p\n", psta); - _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); rtw_free_stainfo(padapter, psta); - _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); psta = NULL; } @@ -9011,37 +9564,32 @@ static int rtw_wowlan_ctrl(struct net_device *dev, if (!check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { +#ifdef CONFIG_PNO_SUPPORT + pwrctrlpriv->wowlan_pno_enable = _TRUE; +#else DBG_871X("[%s] WARNING: Please Connect With AP First!!\n", __func__); goto _rtw_wowlan_ctrl_exit_free; +#endif //CONFIG_PNO_SUPPORT } if (_rtw_memcmp( extra, "enable", 6 )) { padapter->registrypriv.mp_mode = 1; - while (pwrctrlpriv->bips_processing == _TRUE) - rtw_msleep_os(1); - - rtw_ps_deny(padapter, PS_DENY_SUSPEND); + pwrctrlpriv->wowlan_from_cmd = _TRUE; - rtw_cancel_all_timer(padapter); - -#ifdef CONFIG_CONCURRENT_MODE - if (padapter->pbuddy_adapter){ - rtw_cancel_all_timer(padapter->pbuddy_adapter); - } -#endif // CONFIG_CONCURRENT_MODE + rtw_suspend_common(padapter); - LeaveAllPowerSaveModeDirect(padapter); + } else if (_rtw_memcmp( extra, "disable", 6 )) { - rtw_stop_cmd_thread(padapter); + rtw_resume_common(padapter); - rtw_ps_deny_cancel(padapter, PS_DENY_SUSPEND); + pwrctrlpriv->wowlan_from_cmd = _FALSE; - rtw_suspend_wow(padapter); +#ifdef CONFIG_PNO_SUPPORT + pwrctrlpriv->wowlan_pno_enable = _FALSE; +#endif //CONFIG_PNO_SUPPORT - } else if (_rtw_memcmp( extra, "disable", 6 )) { - rtw_resume_process_wow(padapter); padapter->registrypriv.mp_mode = 0; } else { DBG_871X("[%s] Invalid Parameter.\n", __func__); @@ -9844,7 +10392,7 @@ static int rtw_mp_efuse_set(struct net_device *dev, u8 *ShadowMapWiFi = NULL; u8 *setrawdata = NULL; char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00}; - u16 addr=0, cnts=0, BTStatus=0 , max_available_size=0; + u16 addr=0xFF, cnts=0, BTStatus=0 , max_available_size=0; int err; wrqu = (struct iw_point*)wdata; @@ -10099,7 +10647,20 @@ static int rtw_mp_efuse_set(struct net_device *dev, addr = EEPROM_MAC_ADDR_8723BU; #endif #endif // CONFIG_RTL8723B - + + #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + #ifdef CONFIG_SDIO_HCI + addr = EEPROM_MAC_ADDR_8821AS; + #endif + #ifdef CONFIG_PCI_HCI + addr = EEPROM_MAC_ADDR_8821AE; + #endif + #ifdef CONFIG_USB_HCI + addr = EEPROM_MAC_ADDR_8821AU; + #endif + + #endif // CONFIG_RTL8812A/CONFIG_RTL8821A + cnts = strlen(tmp[1]); if (cnts%2) { @@ -10873,6 +11434,8 @@ static int rtw_mp_read_rf(struct net_device *dev, while( *pch != '\0' ) { pnext = strpbrk(pch, " "); + if (!pnext) + break; pnext++; if ( *pnext != '\0' ) { @@ -10934,8 +11497,10 @@ static int rtw_mp_start(struct net_device *dev, rtw_write32(padapter, 0x765, 0x0000); rtw_write32(padapter, 0x948, 0x0000); #endif +#ifdef CONFIG_FOR_RTL8723BS_VQ0 + rtw_write32(padapter, 0x765, 0x0000); + rtw_write32(padapter, 0x948, 0x0280); #endif -#ifdef CONFIG_RTL8723B rtw_write8(padapter, 0x66, 0x27); //Open BT uart Log rtw_write8(padapter, 0xc50, 0x20); //for RX init Gain #endif @@ -10981,19 +11546,26 @@ static int rtw_mp_rate(struct net_device *dev, if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; - rate = rtw_atoi(input); - sprintf( extra, "Set data rate to %d" , rate ); - + rate = rtw_mpRateParseFunc(padapter,input); + + if (rate ==0 && strcmp(input,"1M")!=0) + { + rate = rtw_atoi(input); if(rate <= 0x7f) rate = wifirate2_ratetbl_inx( (u8)rate); - else if (rate < 0x90) - //HT rate 0x80(MCS0) ~ 0x8F(MCS15) 128~143 + else if (rate < 0xC8) rate =(rate - 0x80 + MPT_RATE_MCS0); - else + //HT rate 0x80(MCS0) ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159 + //VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179 + //VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199 + //else //VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153 - rate =(rate - MPT_RATE_VHT1SS_MCS0); + // rate =(rate - MPT_RATE_VHT1SS_MCS0); + } + _rtw_memset(extra, 0, wrqu->length); - //DBG_871X("%s: rate=%d\n", __func__, rate); + sprintf( extra, "Set data rate to %s index %d" ,input,rate ); + DBG_871X("%s: %s rate index=%d \n", __func__,input,rate); if (rate >= MPT_RATE_LAST ) return -EINVAL; @@ -11001,7 +11573,7 @@ static int rtw_mp_rate(struct net_device *dev, padapter->mppriv.rateidx = rate; Hal_SetDataRate(padapter); - wrqu->length = strlen(extra) + 1; + wrqu->length = strlen(extra); return 0; } @@ -11021,14 +11593,13 @@ static int rtw_mp_channel(struct net_device *dev, channel = rtw_atoi(input); //DBG_871X("%s: channel=%d\n", __func__, channel); + _rtw_memset(extra, 0, wrqu->length); sprintf( extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel ); padapter->mppriv.channel = channel; - pHalData->CurrentChannel = channel; Hal_SetChannel(padapter); + pHalData->CurrentChannel = channel; - //cur_ch_offset = rtw_get_offset_by_ch(padapter->mppriv.channel); - //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, padapter->mppriv.bandwidth); - wrqu->length = strlen(extra) + 1; + wrqu->length = strlen(extra); return 0; } @@ -11055,10 +11626,10 @@ static int rtw_mp_bandwidth(struct net_device *dev, DBG_871X("%s: bw=%d sg=%d \n", __func__, bandwidth , sg); padapter->mppriv.bandwidth = (u8)bandwidth; - pHalData->CurrentChannelBW = bandwidth; padapter->mppriv.preamble = sg; SetBandwidth(padapter); + pHalData->CurrentChannelBW = bandwidth; //cur_ch_offset = rtw_get_offset_by_ch(padapter->mppriv.channel); //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, bandwidth); @@ -11084,7 +11655,7 @@ static int rtw_mp_txpower_index(struct net_device *dev, rfpath = rtw_atoi(input); txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath); sprintf(extra, " %d", txpower_inx); - wrqu->length = strlen(extra) + 1; + wrqu->length = strlen(extra); return 0; } @@ -11118,7 +11689,7 @@ static int rtw_mp_txpower(struct net_device *dev, padapter->mppriv.bSetTxPower = 1; Hal_SetAntennaPathPower(padapter); } - wrqu->length = strlen(extra) + 1; + wrqu->length = strlen(extra); return 0; } @@ -11136,7 +11707,7 @@ static int rtw_mp_ant_tx(struct net_device *dev, //DBG_871X("%s: input=%s\n", __func__, input); - sprintf( extra, "switch Tx antenna to %s", input ); + sprintf( extra, "switch Tx antenna to %s", input); for (i=0; i < strlen(input); i++) { @@ -11153,11 +11724,12 @@ static int rtw_mp_ant_tx(struct net_device *dev, //antenna |= BIT(extra[i]-'a'); //DBG_871X("%s: antenna=0x%x\n", __func__, antenna); padapter->mppriv.antenna_tx = antenna; + padapter->mppriv.antenna_rx = antenna; //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx); Hal_SetAntenna(padapter); - wrqu->length = strlen(extra) + 1; + wrqu->length = strlen(extra); return 0; } @@ -11193,6 +11765,7 @@ static int rtw_mp_ant_rx(struct net_device *dev, } //DBG_871X("%s: antenna=0x%x\n", __func__, antenna); + padapter->mppriv.antenna_tx = antenna; padapter->mppriv.antenna_rx = antenna; //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx); Hal_SetAntenna(padapter); @@ -11680,7 +12253,7 @@ static int rtw_mp_thermal(struct net_device *dev, struct iw_point *wrqu, char *extra) { u8 val; - u16 bwrite=1; + int bwrite=1; #ifdef CONFIG_RTL8192C u16 addr=EEPROM_THERMAL_METER_92C; @@ -11921,7 +12494,7 @@ static int rtw_mp_PwrCtlDM(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); u8 input[wrqu->length]; - u8 bstart=1; + int bstart=1; if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -11939,6 +12512,23 @@ static int rtw_mp_PwrCtlDM(struct net_device *dev, return 0; } +static int rtw_mp_getver(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + struct mp_priv *pmp_priv; + + pmp_priv = &padapter->mppriv; + + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + sprintf(extra, "rtwpriv=%d\n",RTWPRIV_VER_INFO); + wrqu->data.length = strlen(extra); + return 0; +} + #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)) /* update Tx AGC offset */ static int rtw_mp_SetBT(struct net_device *dev, @@ -12162,7 +12752,7 @@ static int rtw_mp_SetBT(struct net_device *dev, if ( strncmp(extra, "h2c", 3) == 0){ DBG_871X("SetBT h2c !\n"); padapter->bBTFWReady = _TRUE; - FillH2CCmd(padapter, 0x63, 1, u1H2CBtMpOperParm); + rtw_hal_fill_h2c_cmd(padapter, 0x63, 1, u1H2CBtMpOperParm); goto exit; } if ( strncmp(extra, "2ant", 4) == 0){ @@ -12534,7 +13124,10 @@ static int rtw_mp_get(struct net_device *dev, DBG_871X("mp_get MP_GET_TXPOWER_INX \n"); rtw_mp_txpower_index(dev,info,wrqu,extra); break; - + case MP_GETVER: + DBG_871X("mp_get MP_GETVER \n"); + rtw_mp_getver(dev,info,wdata,extra); + break; #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B) case MP_SetBT: DBG_871X("set MP_SetBT \n"); @@ -13334,6 +13927,14 @@ extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc); extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); #define fill_default_txdesc rtl8723b_fill_default_txdesc #endif // CONFIG_RTL8723B +#if defined(CONFIG_RTL8192E) +extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc); +#define cal_txdesc_chksum rtl8192e_cal_txdesc_chksum +#ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI) +extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); +#define fill_default_txdesc rtl8192es_fill_default_txdesc +#endif // CONFIG_SDIO_HCI +#endif //CONFIG_RTL8192E static s32 initLoopback(PADAPTER padapter) { @@ -14081,64 +14682,6 @@ static iw_handler rtw_handlers[] = NULL, /*---hole---*/ }; -#if 0 -//defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT) -static const struct iw_priv_args rtw_private_args[] = -{ - { SIOCIWFIRSTPRIV + 0x00, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, //set - { SIOCIWFIRSTPRIV + 0x01, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get -/* --- sub-ioctls definitions --- */ - { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set - { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get - { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set - { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get - { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set - { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get - { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"}, - { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" }, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" }, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" }, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" }, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"}, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"}, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"}, - { WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, 0,"write_reg"},//set - { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" }, - { WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, 0,"write_rf"},//set - { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" }, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"}, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"}, - { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set - { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"}, - { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set" }, - { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" }, - { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"}, - { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" }, - { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl - { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" }, -#ifdef CONFIG_RTL8723A - { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" }, -#endif - { SIOCIWFIRSTPRIV + 0x02, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "test"},//set -}; -static iw_handler rtw_private_handler[] = -{ - rtw_mp_set, - rtw_mp_get, -}; -#else // not inlucde MP static const struct iw_priv_args rtw_private_args[] = { { @@ -14290,6 +14833,7 @@ static const struct iw_priv_args rtw_private_args[] = { { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" }, { MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" }, { MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" }, + { MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" }, #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B) { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" }, @@ -14364,7 +14908,6 @@ static iw_handler rtw_private_handler[] = #endif // CONFIG_INTEL_WIDI }; -#endif // #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT) #if WIRELESS_EXT >= 17 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) @@ -14415,7 +14958,9 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) //ODM_InbandNoise_Monitor(podmpriv,_TRUE,0x20,100); rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL); rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(info.chan), &(padapter->recvpriv.noise)); + #ifdef DBG_NOISE_MONITOR DBG_871X("chan:%d,noise_level:%d\n",info.chan,padapter->recvpriv.noise); + #endif } #endif tmp_noise = padapter->recvpriv.noise; @@ -14487,7 +15032,8 @@ static int get_priv_size(__u16 args) } // copy from net/wireless/wext.c end -static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data) + +static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data) { int err = 0; u8 *input = NULL; @@ -14517,10 +15063,9 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_ union iwreq_data wdata; - _rtw_memcpy(&wdata, wrq_data, sizeof(wdata)); - input_len = 2048; + input_len = wdata.data.length; input = rtw_zmalloc(input_len); if (NULL == input) return -ENOMEM; @@ -14529,18 +15074,17 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_ goto exit; } ptr = input; - len = strlen(input); - + len = input_len; sscanf(ptr, "%16s", cmdname); cmdlen = strlen(cmdname); - DBG_8192C("%s: cmd=%s\n", __func__, cmdname); + DBG_871X("%s: cmd=%s\n", __func__, cmdname); // skip command string if (cmdlen > 0) cmdlen += 1; // skip one space ptr += cmdlen; len -= cmdlen; - DBG_8192C("%s: parameters=%s\n", __func__, ptr); + DBG_871X("%s: parameters=%s\n", __func__, ptr); priv = rtw_private_handler; priv_args = rtw_private_args; @@ -14826,6 +15370,61 @@ exit: return err; } +#ifdef CONFIG_COMPAT +static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq) +{ + struct compat_iw_point iwp_compat; + union iwreq_data wrq_data; + int err = 0; + DBG_871X("%s:...\n", __func__); + if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point))) + return -EFAULT; + + wrq_data.data.pointer = compat_ptr(iwp_compat.pointer); + wrq_data.data.length = iwp_compat.length; + wrq_data.data.flags = iwp_compat.flags; + + err = _rtw_ioctl_wext_private(dev, &wrq_data); + + iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer); + iwp_compat.length = wrq_data.data.length; + iwp_compat.flags = wrq_data.data.flags; + if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point))) + return -EFAULT; + + return err; +} +#endif // CONFIG_COMPAT + +static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq) +{ + struct iw_point *iwp; + struct ifreq ifrq; + union iwreq_data wrq_data; + int err = 0; + iwp = &wrq_data.data; + DBG_871X("%s:...\n", __func__); + if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point))) + return -EFAULT; + + err = _rtw_ioctl_wext_private(dev, &wrq_data); + + if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point))) + return -EFAULT; + + return err; +} + +static int rtw_ioctl_wext_private(struct net_device *dev, struct ifreq *rq) +{ +#ifdef CONFIG_COMPAT + if(is_compat_task()) + return rtw_ioctl_compat_wext_private( dev, rq ); + else +#endif // CONFIG_COMPAT + return rtw_ioctl_standard_wext_private( dev, rq ); +} + int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct iwreq *wrq = (struct iwreq *)rq; @@ -14846,8 +15445,8 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; #endif #endif // CONFIG_AP_MODE - case SIOCDEVPRIVATE: - ret = rtw_ioctl_wext_private(dev, &wrq->u); + case SIOCDEVPRIVATE: + ret = rtw_ioctl_wext_private(dev, rq); break; case (SIOCDEVPRIVATE+1): ret = rtw_android_priv_cmd(dev, rq, cmd); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/mlme_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/mlme_linux.c index c2cc56d6e231..ba0ab12f46e6 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/mlme_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/mlme_linux.c @@ -464,11 +464,7 @@ static int mgnt_netdev_open(struct net_device *pnetdev) init_usb_anchor(&phostapdpriv->anchored); - if(!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_start_queue(pnetdev); - else - rtw_netif_wake_queue(pnetdev); - + rtw_netif_wake_queue(pnetdev); netif_carrier_on(pnetdev); @@ -486,9 +482,8 @@ static int mgnt_netdev_close(struct net_device *pnetdev) netif_carrier_off(pnetdev); - if (!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_stop_queue(pnetdev); - + rtw_netif_stop_queue(pnetdev); + //rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f); return 0; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/os_intfs.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/os_intfs.c index f8a0e06a3be1..1eef779c4292 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/os_intfs.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/os_intfs.c @@ -54,7 +54,11 @@ int rtw_adhoc_tx_pwr = 1; int rtw_soft_ap = 0; //int smart_ps = 1; #ifdef CONFIG_POWER_SAVING -int rtw_power_mgnt = 1; +#ifdef CONFIG_PLATFORM_INTEL_BYT +int rtw_power_mgnt = PS_MODE_MAX; +#else +int rtw_power_mgnt = PS_MODE_MIN; +#endif #ifdef CONFIG_IPS_LEVEL_2 int rtw_ips_mode = IPS_LEVEL_2; #else @@ -213,7 +217,11 @@ char* ifname = "wlan%d"; module_param(ifname, charp, 0644); MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); -char* if2name = "p2p0"; +#ifdef CONFIG_PLATFORM_ANDROID +char* if2name = "p2p%d"; +#else //CONFIG_PLATFORM_ANDROID +char* if2name = "wlan%d"; +#endif //CONFIG_PLATFORM_ANDROID module_param(if2name, charp, 0644); MODULE_PARM_DESC(if2name, "The default name to allocate for second interface"); @@ -332,6 +340,30 @@ uint rtw_adaptivity_mode = CONFIG_RTW_ADAPTIVITY_MODE; module_param(rtw_adaptivity_mode, uint, 0644); MODULE_PARM_DESC(rtw_adaptivity_mode, "0:normal, 1:carrier sense"); +uint rtw_nhm_en = CONFIG_RTW_NHM_EN; +module_param(rtw_nhm_en, uint, 0644); +MODULE_PARM_DESC(rtw_nhm_en, "0:disable, 1:enable"); + +uint rtw_amplifier_type_2g = CONFIG_RTW_AMPLIFIER_TYPE_2G; +module_param(rtw_amplifier_type_2g, uint, 0644); +MODULE_PARM_DESC(rtw_amplifier_type_2g, "BIT3:2G ext-PA, BIT4:2G ext-LNA"); + +uint rtw_amplifier_type_5g = CONFIG_RTW_AMPLIFIER_TYPE_5G; +module_param(rtw_amplifier_type_5g, uint, 0644); +MODULE_PARM_DESC(rtw_amplifier_type_5g, "BIT6:5G ext-PA, BIT7:5G ext-LNA"); + +uint rtw_RFE_type = 64; +module_param(rtw_RFE_type, uint, 0644); +MODULE_PARM_DESC(rtw_RFE_type, "default init value:64"); + +uint rtw_TxBBSwing_2G = 0xFF; +module_param(rtw_TxBBSwing_2G, uint, 0644); +MODULE_PARM_DESC(rtw_TxBBSwing_2G, "default init value:0xFF"); + +uint rtw_TxBBSwing_5G = 0xFF; +module_param(rtw_TxBBSwing_5G, uint, 0644); +MODULE_PARM_DESC(rtw_TxBBSwing_5G, "default init value:0xFF"); + #if defined(CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY) //eFuse: Regulatory selection=1 int rtw_tx_pwr_lmt_enable = 1; int rtw_tx_pwr_by_rate = 1; @@ -355,7 +387,7 @@ module_param(rtw_tx_pwr_by_rate, int, 0644); MODULE_PARM_DESC(rtw_tx_pwr_by_rate,"0:Disable, 1:Enable, 2: Depend on efuse"); #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE -char *rtw_phy_file_path = ""; +char *rtw_phy_file_path = REALTEK_CONFIG_PATH; module_param(rtw_phy_file_path, charp, 0644); MODULE_PARM_DESC(rtw_phy_file_path, "The path of phy parameter"); // PHY FILE Bit Map @@ -378,6 +410,9 @@ static uint loadparam(PADAPTER padapter, _nic_hdl pnetdev); int _netdev_open(struct net_device *pnetdev); int netdev_open (struct net_device *pnetdev); static int netdev_close (struct net_device *pnetdev); +#ifdef CONFIG_PLATFORM_INTEL_BYT +extern int rtw_sdio_set_power(int on); +#endif //CONFIG_PLATFORM_INTEL_BYT //#ifdef RTK_DMP_PLATFORM uint loadparam( _adapter *padapter, _nic_hdl pnetdev) @@ -539,10 +574,12 @@ _func_enter_; registry_par->RegEnableTxPowerByRate = (u8)rtw_tx_pwr_by_rate; registry_par->RegPowerBase = 14; - registry_par->TxBBSwing_2G = 0xFF; - registry_par->TxBBSwing_5G = 0xFF; + registry_par->TxBBSwing_2G = (s8)rtw_TxBBSwing_2G; + registry_par->TxBBSwing_5G = (s8)rtw_TxBBSwing_5G; registry_par->bEn_RFE = 1; - registry_par->RFE_Type = 64; + registry_par->RFE_Type = (u8)rtw_RFE_type; + registry_par->AmplifierType_2G = (u8)rtw_amplifier_type_2g; + registry_par->AmplifierType_5G = (u8)rtw_amplifier_type_5g; #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE registry_par->load_phy_file = (u8)rtw_load_phy_file; @@ -551,8 +588,11 @@ _func_enter_; registry_par->qos_opt_enable = (u8)rtw_qos_opt_enable; registry_par->hiq_filter = (u8)rtw_hiq_filter; + registry_par->adaptivity_en = (u8)rtw_adaptivity_en; registry_par->adaptivity_mode = (u8)rtw_adaptivity_mode; + registry_par->nhm_en = (u8)rtw_nhm_en; + _func_exit_; return status; @@ -626,14 +666,16 @@ unsigned int rtw_classify8021d(struct sk_buff *skb) return dscp >> 5; } + static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) - , void *accel_priv -#endif // kernle >= 3.13 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) - , select_queue_fallback_t fallback -#endif // kernel >= 3.14 - ) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + , void *accel_priv +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + , select_queue_fallback_t fallback +#endif + +#endif +) { _adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -677,14 +719,13 @@ u16 rtw_recv_select_queue(struct sk_buff *skb) } #endif - static int rtw_ndev_notifier_call(struct notifier_block * nb, unsigned long state, void *ptr) -{ +{ #if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,11,0)) struct net_device *dev = netdev_notifier_info_to_dev(ptr); -#else // kernel < 3.11 +#else struct net_device *dev = ptr; -#endif // kernel < 3.11 +#endif #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) if (dev->netdev_ops->ndo_do_ioctl != rtw_ioctl) @@ -1052,8 +1093,10 @@ u8 rtw_init_default_value(_adapter *padapter) //for debug purpose padapter->fix_rate = 0xFF; + padapter->data_fb = 0; padapter->driver_ampdu_spacing = 0xFF; padapter->driver_rx_ampdu_factor = 0xFF; + padapter->driver_rx_ampdu_spacing = 0xFF; padapter->fix_ba_rxbuf_bz = 0xFF; return ret; @@ -1073,17 +1116,15 @@ struct dvobj_priv *devobj_init(void) _rtw_mutex_init(&pdvobj->setch_mutex); _rtw_mutex_init(&pdvobj->setbw_mutex); - _rtw_spinlock_init(&pdvobj->lock); - - pdvobj->macid[1] = _TRUE; //macid=1 for bc/mc stainfo - pdvobj->processing_dev_remove = _FALSE; ATOMIC_SET(&pdvobj->disable_func, 0); + rtw_macid_ctl_init(&pdvobj->macid_ctl); _rtw_spinlock_init(&pdvobj->cam_ctl.lock); return pdvobj; + } void devobj_deinit(struct dvobj_priv *pdvobj) @@ -1091,17 +1132,16 @@ void devobj_deinit(struct dvobj_priv *pdvobj) if(!pdvobj) return; - _rtw_spinlock_free(&pdvobj->lock); - _rtw_mutex_free(&pdvobj->hw_init_mutex); _rtw_mutex_free(&pdvobj->h2c_fwcmd_mutex); _rtw_mutex_free(&pdvobj->setch_mutex); _rtw_mutex_free(&pdvobj->setbw_mutex); + rtw_macid_ctl_deinit(&pdvobj->macid_ctl); _rtw_spinlock_free(&pdvobj->cam_ctl.lock); rtw_mfree((u8*)pdvobj, sizeof(*pdvobj)); -} +} u8 rtw_reset_drv_sw(_adapter *padapter) { @@ -1162,8 +1202,6 @@ _func_enter_; ret8 = rtw_init_default_value(padapter); - rtw_init_hal_com_default_value(padapter); - if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init cmd_priv\n")); @@ -1248,6 +1286,7 @@ _func_enter_; padapter->stapriv.padapter = padapter; padapter->setband = GHZ24_50; padapter->fix_rate = 0xFF; + padapter->data_fb = 0; padapter->fix_ba_rxbuf_bz = 0xFF; rtw_init_bcmc_stainfo(padapter); @@ -1482,11 +1521,7 @@ int _netdev_vir_if_open(struct net_device *pnetdev) _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); - if(!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_start_queue(pnetdev); - else - rtw_netif_wake_queue(pnetdev); - + rtw_netif_wake_queue(pnetdev); DBG_871X(FUNC_NDEV_FMT" exit\n", FUNC_NDEV_ARG(pnetdev)); return 0; @@ -1527,8 +1562,7 @@ static int netdev_vir_if_close(struct net_device *pnetdev) if(pnetdev) { - if (!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_stop_queue(pnetdev); + rtw_netif_stop_queue(pnetdev); } #ifdef CONFIG_IOCTL_CFG80211 @@ -1800,6 +1834,42 @@ int _netdev_if2_open(struct net_device *pnetdev) DBG_871X("+871x_drv - if2_open, bup=%d\n", padapter->bup); +#ifdef CONFIG_PLATFORM_INTEL_BYT + if (padapter->bup == _FALSE) + { + u8 mac[ETH_ALEN]; + + //get mac address from primary_padapter + if (primary_padapter->bup == _FALSE) + rtw_macaddr_cfg(primary_padapter->eeprompriv.mac_addr); + + _rtw_memcpy(mac, primary_padapter->eeprompriv.mac_addr, ETH_ALEN); + + if (((mac[0] == 0xff) && (mac[1] == 0xff) && (mac[2] == 0xff) && + (mac[3] == 0xff) && (mac[4] == 0xff) && (mac[5] == 0xff)) || + ((mac[0] == 0x0) && (mac[1] == 0x0) && (mac[2] == 0x0) && + (mac[3] == 0x0) && (mac[4] == 0x0) && (mac[5] == 0x0))) + { + mac[0] = 0x00; + mac[1] = 0xe0; + mac[2] = 0x4c; + mac[3] = 0x87; + mac[4] = 0x11; + mac[5] = 0x22; + } + else + { + //If the BIT1 is 0, the address is universally administered. + //If it is 1, the address is locally administered + mac[0] |= BIT(1); // locally administered + } + + _rtw_memcpy(padapter->eeprompriv.mac_addr, mac, ETH_ALEN); + rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, padapter->eeprompriv.mac_addr); + _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); + } +#endif //CONFIG_PLATFORM_INTEL_BYT + if(primary_padapter->bup == _FALSE || primary_padapter->hw_init_completed == _FALSE) { _netdev_open(primary_padapter->pnetdev); @@ -1845,10 +1915,7 @@ int _netdev_if2_open(struct net_device *pnetdev) // secondary interface shares the timer with primary interface. //_set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); - if(!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_start_queue(pnetdev); - else - rtw_netif_wake_queue(pnetdev); + rtw_netif_wake_queue(pnetdev); DBG_871X("-871x_drv - if2_open, bup=%d\n", padapter->bup); return 0; @@ -1870,9 +1937,9 @@ int netdev_if2_open(struct net_device *pnetdev) _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); - - if (pwrctrlpriv->bInSuspend == _TRUE) { - DBG_871X(FUNC_ADPT_FMT ": bInSuspend=%d\n", FUNC_ADPT_ARG(padapter), pwrctrlpriv->bInSuspend); + if (pwrctrlpriv->bInSuspend == _TRUE) + { + DBG_871X("+871x_drv - netdev_if2_open, bInSuspend=%d\n", pwrctrlpriv->bInSuspend); return 0; } @@ -1896,8 +1963,7 @@ static int netdev_if2_close(struct net_device *pnetdev) if(pnetdev) { - if (!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_stop_queue(pnetdev); + rtw_netif_stop_queue(pnetdev); } #ifdef CONFIG_P2P @@ -2243,6 +2309,10 @@ int _netdev_open(struct net_device *pnetdev) padapter->netif_up = _TRUE; +#ifdef CONFIG_PLATFORM_INTEL_BYT + rtw_sdio_set_power(1); +#endif //CONFIG_PLATFORM_INTEL_BYT + if(pwrctrlpriv->ps_flag == _TRUE){ padapter->net_closed = _FALSE; goto netdev_open_normal_process; @@ -2250,6 +2320,12 @@ int _netdev_open(struct net_device *pnetdev) if(padapter->bup == _FALSE) { +#ifdef CONFIG_PLATFORM_INTEL_BYT + rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); + rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, padapter->eeprompriv.mac_addr); + _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); +#endif //CONFIG_PLATFORM_INTEL_BYT + padapter->bDriverStopped = _FALSE; padapter->bSurpriseRemoved = _FALSE; padapter->bCardDisableWOHSM = _FALSE; @@ -2287,6 +2363,12 @@ int _netdev_open(struct net_device *pnetdev) padapter->bup = _TRUE; pwrctrlpriv->bips_processing = _FALSE; + +#ifdef CONFIG_PLATFORM_INTEL_BYT +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_IpsNotify(padapter, IPS_NONE); +#endif // CONFIG_BT_COEXIST +#endif //CONFIG_PLATFORM_INTEL_BYT } padapter->net_closed = _FALSE; @@ -2297,10 +2379,7 @@ int _netdev_open(struct net_device *pnetdev) #endif //netif_carrier_on(pnetdev);//call this func when rtw_joinbss_event_callback return success - if(!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_start_queue(pnetdev); - else - rtw_netif_wake_queue(pnetdev); + rtw_netif_wake_queue(pnetdev); #ifdef CONFIG_BR_EXT netdev_br_init(pnetdev); @@ -2495,6 +2574,7 @@ static int netdev_close(struct net_device *pnetdev) RT_TRACE(_module_os_intfs_c_,_drv_info_,("+871x_drv - drv_close\n")); +#ifndef CONFIG_PLATFORM_INTEL_BYT if(pwrctl->bInternalAutoSuspend == _TRUE) { //rtw_pwr_wakeup(padapter); @@ -2519,8 +2599,7 @@ static int netdev_close(struct net_device *pnetdev) //s1. if(pnetdev) { - if (!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_stop_queue(pnetdev); + rtw_netif_stop_queue(pnetdev); } #ifndef CONFIG_ANDROID @@ -2559,6 +2638,24 @@ static int netdev_close(struct net_device *pnetdev) #ifdef CONFIG_WAPI_SUPPORT rtw_wapi_disable_tx(padapter); #endif +#else //!CONFIG_PLATFORM_INTEL_BYT + + if (pwrctl->bInSuspend == _TRUE) + { + DBG_871X("+871x_drv - drv_close, bInSuspend=%d\n", pwrctl->bInSuspend); + return 0; + } + + rtw_scan_abort(padapter); // stop scanning process before wifi is going to down + + DBG_871X("netdev_close, bips_processing=%d\n", pwrctl->bips_processing); + while (pwrctl->bips_processing == _TRUE) // waiting for ips_processing done before call rtw_dev_unload() + rtw_msleep_os(1); + + rtw_dev_unload(padapter); + rtw_sdio_set_power(0); + +#endif //!CONFIG_PLATFORM_INTEL_BYT RT_TRACE(_module_os_intfs_c_,_drv_info_,("-871x_drv - drv_close\n")); DBG_871X("-871x_drv - drv_close, bup=%d\n", padapter->bup); @@ -2839,11 +2936,17 @@ static int get_defaultgw(u32 *ip_addr ,char mac[]) int rtw_gw_addr_query(_adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); u32 gw_addr = 0; // default gw address unsigned char gw_mac[32] = {0}; // default gw mac int i; int res; + if (pwrctl->wowlan_from_cmd == _TRUE) { + DBG_871X("%s: return cuz wowlan_from_cmd\n", __func__); + return 0; + } + res = get_defaultgw(&gw_addr, gw_mac); if(!res) { @@ -2951,14 +3054,19 @@ int rtw_suspend_free_assoc_resource(_adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct net_device *pnetdev = padapter->pnetdev; +#ifdef CONFIG_P2P struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif // CONFIG_P2P DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) - && rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) +#ifdef CONFIG_P2P + && rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) +#endif // CONFIG_P2P + ) { DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__, pmlmepriv->cur_network.network.Ssid.Ssid, @@ -3025,6 +3133,9 @@ int rtw_suspend_wow(_adapter *padapter) DBG_871X("wowlan_mode: %d\n", pwrpriv->wowlan_mode); DBG_871X("wowlan_pno_enable: %d\n", pwrpriv->wowlan_pno_enable); +#ifdef CONFIG_P2P_WOWLAN + DBG_871X("wowlan_p2p_enable: %d\n", pwrpriv->wowlan_p2p_enable); +#endif if (pwrpriv->wowlan_mode == _TRUE) { if(pnetdev) @@ -3118,8 +3229,10 @@ int rtw_suspend_wow(_adapter *padapter) } #endif - if(pwrpriv->wowlan_pno_enable) - DBG_871X_LEVEL(_drv_always_, "%s: pno: %d\n", __func__, pwrpriv->wowlan_pno_enable); + if(pwrpriv->wowlan_pno_enable) { + DBG_871X_LEVEL(_drv_always_, "%s: pno: %d\n", __func__, + pwrpriv->wowlan_pno_enable); + } #ifdef CONFIG_LPS else rtw_set_ps_mode(padapter, PS_MODE_DTIM, 0, 0, "WOWLAN"); @@ -3370,6 +3483,10 @@ int rtw_suspend_common(_adapter *padapter) } #endif // CONFIG_BT_COEXIST +#if defined(CONFIG_WOWLAN) && defined(CONFIG_GPIO_WAKEUP) + rtw_clear_hostwakeupgpio(padapter); +#endif // CONFIG_WOWLAN && CONFIG_GPIO_WAKEUP + rtw_ps_deny_cancel(padapter, PS_DENY_SUSPEND); if (check_fwstate(pmlmepriv,WIFI_STATION_STATE) == _TRUE @@ -3384,8 +3501,17 @@ int rtw_suspend_common(_adapter *padapter) pwrpriv->wowlan_mode |= pwrpriv->wowlan_pno_enable; } - if (pwrpriv->wowlan_mode == _TRUE) - rtw_suspend_wow(padapter); + #ifdef CONFIG_P2P_WOWLAN + if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE) || P2P_ROLE_DISABLE != padapter->wdinfo.role) + { + pwrpriv->wowlan_p2p_mode = _TRUE; + } + if(_TRUE == pwrpriv->wowlan_p2p_mode) + pwrpriv->wowlan_mode |= pwrpriv->wowlan_p2p_mode; + #endif //CONFIG_P2P_WOWLAN + + if (pwrpriv->wowlan_mode == _TRUE) + rtw_suspend_wow(padapter); else rtw_suspend_normal(padapter); @@ -3542,10 +3668,7 @@ _func_enter_; // start netif queue if (pnetdev) { - if(!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_start_queue(pnetdev); - else - rtw_netif_wake_queue(pnetdev); + rtw_netif_wake_queue(pnetdev); } } else{ @@ -3717,20 +3840,14 @@ _func_enter_; if (rtw_buddy_adapter_up(padapter)) { pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; if(pbuddy_netdev){ - if (!rtw_netif_queue_stopped(pbuddy_netdev)) - rtw_netif_start_queue(pbuddy_netdev); - else - rtw_netif_wake_queue(pbuddy_netdev); + rtw_netif_wake_queue(pbuddy_netdev); } } #endif // start netif queue if (pnetdev) { - if(!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_start_queue(pnetdev); - else - rtw_netif_wake_queue(pnetdev); + rtw_netif_wake_queue(pnetdev); } if( padapter->pid[1]!=0) { @@ -3891,6 +4008,9 @@ int rtw_resume_common(_adapter *padapter) _func_enter_; + if (pwrpriv->bInSuspend == _FALSE) + return 0; + DBG_871X_LEVEL(_drv_always_, "resume start\n"); DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); @@ -3949,3 +4069,28 @@ int rtw_resume_common(_adapter *padapter) return ret; } +#ifdef CONFIG_GPIO_API +u8 rtw_get_gpio(struct net_device *netdev, u8 gpio_num) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + return rtw_hal_get_gpio(adapter, gpio_num); +} +EXPORT_SYMBOL(rtw_get_gpio); + +int rtw_set_gpio_output_value(struct net_device *netdev, u8 gpio_num, BOOLEAN isHigh) +{ + u8 direction = 0; + u8 res = -1; + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + return rtw_hal_set_gpio_output_value(adapter, gpio_num,isHigh); +} +EXPORT_SYMBOL(rtw_set_gpio_output_value); + +int rtw_config_gpio(struct net_device *netdev, u8 gpio_num, BOOLEAN isOutput) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + return rtw_hal_config_gpio(adapter,gpio_num,isOutput); +} +EXPORT_SYMBOL(rtw_config_gpio); +#endif //#ifdef CONFIG_GPIO_API + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/recv_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/recv_linux.c index 57fc16f73368..2c2a47ab66a3 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/recv_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/recv_linux.c @@ -302,6 +302,7 @@ _pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attrib *pattrib) { struct mlme_priv*pmlmepriv = &padapter->mlmepriv; + struct recv_priv *precvpriv = &(padapter->recvpriv); #ifdef CONFIG_BR_EXT void *br_port = NULL; #endif @@ -388,7 +389,8 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attri } } #endif // CONFIG_BR_EXT - + if( precvpriv->sink_udpport > 0) + rtw_sink_rtp_seq_dbg(padapter,pkt); pkt->protocol = eth_type_trans(pkt, padapter->pnetdev); pkt->dev = padapter->pnetdev; @@ -569,12 +571,13 @@ int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame) _queue *pfree_recv_queue; _pkt *skb; struct mlme_priv*pmlmepriv = &padapter->mlmepriv; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - -_func_enter_; + struct rx_pkt_attrib *pattrib; + + if(NULL == precv_frame) + goto _recv_indicatepkt_drop; DBG_COUNTER(padapter->rx_logs.os_indicate); - + pattrib = &precv_frame->u.hdr.attrib; precvpriv = &(padapter->recvpriv); pfree_recv_queue = &(precvpriv->free_recv_queue); @@ -642,7 +645,6 @@ _recv_indicatepkt_end: RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_os_recv_indicate_pkt!!!!\n")); -_func_exit_; return _SUCCESS; @@ -653,9 +655,8 @@ _recv_indicatepkt_drop: rtw_free_recvframe(precv_frame, pfree_recv_queue); DBG_COUNTER(padapter->rx_logs.os_indicate_err); - return _FAIL; -_func_exit_; + return _FAIL; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_android.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_android.c index 1c9ada1e407a..abb99f087d4f 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_android.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_android.c @@ -161,7 +161,8 @@ typedef struct compat_android_wifi_priv_cmd { */ static int g_wifi_on = _TRUE; -unsigned int oob_irq; +unsigned int oob_irq = 0; +unsigned int oob_gpio = 0; #ifdef CONFIG_PNO_SUPPORT /* @@ -443,31 +444,11 @@ int rtw_android_getband(struct net_device *net, char *command, int total_len) return bytes_written; } -enum { - MIRACAST_DISABLED = 0, - MIRACAST_SOURCE, - MIRACAST_SINK, - MIRACAST_INVALID, -}; - -static const char *miracast_mode_str[] = { - "DISABLED", - "SOURCE", - "SINK", - "INVALID", -}; - -static const char *get_miracast_mode_str(int mode) -{ - if (mode < MIRACAST_DISABLED || mode >= MIRACAST_INVALID) - mode = MIRACAST_INVALID; - - return miracast_mode_str[mode]; -} - +#ifdef CONFIG_WFD int rtw_android_set_miracast_mode(struct net_device *net, char *command, int total_len) { _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + struct wifi_display_info *wfd_info = &adapter->wfd_info; char *arg = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_MIRACAST]) + 1; u8 mode; int num; @@ -476,12 +457,14 @@ int rtw_android_set_miracast_mode(struct net_device *net, char *command, int tot num = sscanf(arg, "%hhu", &mode); if (num >= 1) { - DBG_871X("Miracast mode: %s(%u)\n", get_miracast_mode_str(mode), mode); + wfd_info->stack_wfd_mode = mode; + DBG_871X("Miracast mode: %s(%u)\n", get_miracast_mode_str(wfd_info->stack_wfd_mode), wfd_info->stack_wfd_mode); ret = _SUCCESS; } - return (ret==_SUCCESS)?0:-1; + return (ret == _SUCCESS)?0:-1; } +#endif /* CONFIG_WFD */ int get_int_from_command( char* pcmd ) { @@ -709,10 +692,6 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) bytes_written = rtw_android_getband(net, command, priv_cmd.total_len); break; - case ANDROID_WIFI_CMD_MIRACAST: - bytes_written = rtw_android_set_miracast_mode(net, command, priv_cmd.total_len); - break; - case ANDROID_WIFI_CMD_COUNTRY: bytes_written = rtw_android_set_country(net, command, priv_cmd.total_len); break; @@ -756,6 +735,10 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) #endif //CONFIG_IOCTL_CFG80211 #ifdef CONFIG_WFD + case ANDROID_WIFI_CMD_MIRACAST: + bytes_written = rtw_android_set_miracast_mode(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_WFD_ENABLE: { // Commented by Albert 2012/07/24 @@ -848,17 +831,18 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) } #ifdef CONFIG_GTK_OL case ANDROID_WIFI_CMD_GTK_REKEY_OFFLOAD: - rtw_gtk_offload(net, (u8 *)&priv_cmd.buf); + rtw_gtk_offload(net, (u8*)command); break; #endif //CONFIG_GTK_OL case ANDROID_WIFI_CMD_P2P_DISABLE: { +#ifdef CONFIG_P2P struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct wifidirect_info *pwdinfo= &(padapter->wdinfo); u8 channel, ch_offset; u16 bwmode; rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); +#endif // CONFIG_P2P break; } default: @@ -910,14 +894,9 @@ static struct resource *wifi_irqres = NULL; static int wifi_add_dev(void); static void wifi_del_dev(void); -extern int rockchip_wifi_get_oob_irq(void); int rtw_android_wifictrl_func_add(void) { int ret = 0; -#if 1 - oob_irq = rockchip_wifi_get_oob_irq(); - printk("%s: rockchip_wifi_get_oob_irq :%d\n", __func__, oob_irq); -#else sema_init(&wifi_control_sem, 0); ret = wifi_add_dev(); @@ -932,22 +911,20 @@ int rtw_android_wifictrl_func_add(void) ret = -EINVAL; DBG_871X("%s: platform_driver_register timeout\n", __FUNCTION__); } -#endif + return ret; } void rtw_android_wifictrl_func_del(void) { -#if 0 if (g_wifidev_registered) { wifi_del_dev(); g_wifidev_registered = 0; } -#endif } -void *rtw_wl_android_prealloc(int section, unsigned long size) +void *wl_android_prealloc(int section, unsigned long size) { void *alloc_ptr = NULL; if (wifi_control_data && wifi_control_data->mem_prealloc) { @@ -1043,9 +1020,13 @@ static int wifi_probe(struct platform_device *pdev) wifi_irqres->start, wifi_wake_gpio); if (wifi_wake_gpio > 0) { +#ifdef CONFIG_PLATFORM_INTEL_BYT + wifi_configure_gpio(); +#else //CONFIG_PLATFORM_INTEL_BYT gpio_request(wifi_wake_gpio, "oob_irq"); gpio_direction_input(wifi_wake_gpio); oob_irq = gpio_to_irq(wifi_wake_gpio); +#endif //CONFIG_PLATFORM_INTEL_BYT printk("%s oob_irq:%d\n", __func__, oob_irq); } else if(wifi_irqres) @@ -1233,3 +1214,34 @@ static void wifi_del_dev(void) } #endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */ +#ifdef CONFIG_GPIO_WAKEUP +#ifdef CONFIG_PLATFORM_INTEL_BYT +int wifi_configure_gpio(void) +{ + if (gpio_request(oob_gpio, "oob_irq")) { + DBG_871X("## %s Cannot request GPIO\n", __FUNCTION__); + return -1; + } + gpio_export(oob_gpio, 0); + if (gpio_direction_input(oob_gpio)) { + DBG_871X("## %s Cannot set GPIO direction input\n", __FUNCTION__); + return -1; + } + if ((oob_irq = gpio_to_irq(oob_gpio)) < 0) { + DBG_871X("## %s Cannot convert GPIO to IRQ\n", __FUNCTION__); + return -1; + } + + DBG_871X("## %s OOB_IRQ=%d\n", __FUNCTION__, oob_irq); + + return 0; +} +#endif //CONFIG_PLATFORM_INTEL_BYT +void wifi_free_gpio(unsigned int gpio) +{ +#ifdef CONFIG_PLATFORM_INTEL_BYT + if(gpio) + gpio_free(gpio); +#endif //CONFIG_PLATFORM_INTEL_BYT +} +#endif //CONFIG_GPIO_WAKEUP diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_cfgvendor.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_cfgvendor.c new file mode 100755 index 000000000000..2e249c92c6dd --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_cfgvendor.c @@ -0,0 +1,1319 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2014 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#include + +/* +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ + +#include + +#ifdef CONFIG_IOCTL_CFG80211 + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) + +#ifdef DBG_MEM_ALLOC +extern bool match_mstat_sniff_rules(const enum mstat_f flags, const size_t size); +struct sk_buff * dbg_rtw_cfg80211_vendor_event_alloc(struct wiphy *wiphy, int len, int event_id, gfp_t gfp + , const enum mstat_f flags, const char *func, const int line) +{ + struct sk_buff *skb; + unsigned int truesize = 0; + + skb = cfg80211_vendor_event_alloc(wiphy, len, event_id, gfp); + + if(skb) + truesize = skb->truesize; + + if(!skb || truesize < len || match_mstat_sniff_rules(flags, truesize)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d), skb:%p, truesize=%u\n", func, line, __FUNCTION__, len, skb, truesize); + + rtw_mstat_update( + flags + , skb ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb; +} + +void dbg_rtw_cfg80211_vendor_event(struct sk_buff *skb, gfp_t gfp + , const enum mstat_f flags, const char *func, const int line) +{ + unsigned int truesize = skb->truesize; + + if(match_mstat_sniff_rules(flags, truesize)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize); + + cfg80211_vendor_event(skb, gfp); + + rtw_mstat_update( + flags + , MSTAT_FREE + , truesize + ); +} + +struct sk_buff *dbg_rtw_cfg80211_vendor_cmd_alloc_reply_skb(struct wiphy *wiphy, int len + , const enum mstat_f flags, const char *func, const int line) +{ + struct sk_buff *skb; + unsigned int truesize = 0; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); + + if(skb) + truesize = skb->truesize; + + if(!skb || truesize < len || match_mstat_sniff_rules(flags, truesize)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d), skb:%p, truesize=%u\n", func, line, __FUNCTION__, len, skb, truesize); + + rtw_mstat_update( + flags + , skb ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb; +} + +int dbg_rtw_cfg80211_vendor_cmd_reply(struct sk_buff *skb + , const enum mstat_f flags, const char *func, const int line) +{ + unsigned int truesize = skb->truesize; + int ret; + + if(match_mstat_sniff_rules(flags, truesize)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize); + + ret = cfg80211_vendor_cmd_reply(skb); + + rtw_mstat_update( + flags + , MSTAT_FREE + , truesize + ); + + return ret; +} + +#define rtw_cfg80211_vendor_event_alloc(wiphy, len, event_id, gfp) \ + dbg_rtw_cfg80211_vendor_event_alloc(wiphy, len, event_id, gfp, MSTAT_FUNC_CFG_VENDOR|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) + +#define rtw_cfg80211_vendor_event(skb, gfp) \ + dbg_rtw_cfg80211_vendor_event(skb, gfp, MSTAT_FUNC_CFG_VENDOR|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) + +#define rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len) \ + dbg_rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len, MSTAT_FUNC_CFG_VENDOR|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) + +#define rtw_cfg80211_vendor_cmd_reply(skb) \ + dbg_rtw_cfg80211_vendor_cmd_reply(skb, MSTAT_FUNC_CFG_VENDOR|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#else +#define rtw_cfg80211_vendor_event_alloc(wiphy, len, event_id, gfp) \ + cfg80211_vendor_event_alloc(wiphy, len, event_id, gfp) + +#define rtw_cfg80211_vendor_event(skb, gfp) \ + cfg80211_vendor_event(skb, gfp) + +#define rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len) \ + cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len) + +#define rtw_cfg80211_vendor_cmd_reply(skb) \ + cfg80211_vendor_cmd_reply(skb) +#endif /* DBG_MEM_ALLOC */ + +/* + * This API is to be used for asynchronous vendor events. This + * shouldn't be used in response to a vendor command from its + * do_it handler context (instead rtw_cfgvendor_send_cmd_reply should + * be used). + */ +int rtw_cfgvendor_send_async_event(struct wiphy *wiphy, + struct net_device *dev, int event_id, const void *data, int len) +{ + u16 kflags; + struct sk_buff *skb; + + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + + /* Alloc the SKB for vendor_event */ + skb = rtw_cfg80211_vendor_event_alloc(wiphy, len, event_id, kflags); + if (!skb) { + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(dev)); + return -ENOMEM; + } + + /* Push the data to the skb */ + nla_put_nohdr(skb, len, data); + + rtw_cfg80211_vendor_event(skb, kflags); + + return 0; +} + +static int rtw_cfgvendor_send_cmd_reply(struct wiphy *wiphy, + struct net_device *dev, const void *data, int len) +{ + struct sk_buff *skb; + + /* Alloc the SKB for vendor_event */ + skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); + if (unlikely(!skb)) { + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(dev)); + return -ENOMEM; + } + + /* Push the data to the skb */ + nla_put_nohdr(skb, len, data); + + return rtw_cfg80211_vendor_cmd_reply(skb); +} + +#define WIFI_FEATURE_INFRA 0x0001 /* Basic infrastructure mode */ +#define WIFI_FEATURE_INFRA_5G 0x0002 /* Support for 5 GHz Band */ +#define WIFI_FEATURE_HOTSPOT 0x0004 /* Support for GAS/ANQP */ +#define WIFI_FEATURE_P2P 0x0008 /* Wifi-Direct */ +#define WIFI_FEATURE_SOFT_AP 0x0010 /* Soft AP */ +#define WIFI_FEATURE_GSCAN 0x0020 /* Google-Scan APIs */ +#define WIFI_FEATURE_NAN 0x0040 /* Neighbor Awareness Networking */ +#define WIFI_FEATURE_D2D_RTT 0x0080 /* Device-to-device RTT */ +#define WIFI_FEATURE_D2AP_RTT 0x0100 /* Device-to-AP RTT */ +#define WIFI_FEATURE_BATCH_SCAN 0x0200 /* Batched Scan (legacy) */ +#define WIFI_FEATURE_PNO 0x0400 /* Preferred network offload */ +#define WIFI_FEATURE_ADDITIONAL_STA 0x0800 /* Support for two STAs */ +#define WIFI_FEATURE_TDLS 0x1000 /* Tunnel directed link setup */ +#define WIFI_FEATURE_TDLS_OFFCHANNEL 0x2000 /* Support for TDLS off channel */ +#define WIFI_FEATURE_EPR 0x4000 /* Enhanced power reporting */ +#define WIFI_FEATURE_AP_STA 0x8000 /* Support for AP STA Concurrency */ + +#define MAX_FEATURE_SET_CONCURRRENT_GROUPS 3 + +#include +int rtw_dev_get_feature_set(struct net_device *dev) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter); + HAL_VERSION *hal_ver = &HalData->VersionID; + + int feature_set = 0; + + feature_set |= WIFI_FEATURE_INFRA; + + if(IS_92D(*hal_ver) || IS_8812_SERIES(*hal_ver) || IS_8821_SERIES(*hal_ver)) + feature_set |= WIFI_FEATURE_INFRA_5G; + + feature_set |= WIFI_FEATURE_P2P; + feature_set |= WIFI_FEATURE_SOFT_AP; + + feature_set |= WIFI_FEATURE_ADDITIONAL_STA; + + return feature_set; +} + +int *rtw_dev_get_feature_set_matrix(struct net_device *dev, int *num) +{ + int feature_set_full, mem_needed; + int *ret; + + *num = 0; + mem_needed = sizeof(int) * MAX_FEATURE_SET_CONCURRRENT_GROUPS; + ret = (int *)rtw_malloc(mem_needed); + + if (!ret) { + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" failed to allocate %d bytes\n" + , FUNC_NDEV_ARG(dev), mem_needed); + return ret; + } + + feature_set_full = rtw_dev_get_feature_set(dev); + + ret[0] = (feature_set_full & WIFI_FEATURE_INFRA) | + (feature_set_full & WIFI_FEATURE_INFRA_5G) | + (feature_set_full & WIFI_FEATURE_NAN) | + (feature_set_full & WIFI_FEATURE_D2D_RTT) | + (feature_set_full & WIFI_FEATURE_D2AP_RTT) | + (feature_set_full & WIFI_FEATURE_PNO) | + (feature_set_full & WIFI_FEATURE_BATCH_SCAN) | + (feature_set_full & WIFI_FEATURE_GSCAN) | + (feature_set_full & WIFI_FEATURE_HOTSPOT) | + (feature_set_full & WIFI_FEATURE_ADDITIONAL_STA) | + (feature_set_full & WIFI_FEATURE_EPR); + + ret[1] = (feature_set_full & WIFI_FEATURE_INFRA) | + (feature_set_full & WIFI_FEATURE_INFRA_5G) | + /* Not yet verified NAN with P2P */ + /* (feature_set_full & WIFI_FEATURE_NAN) | */ + (feature_set_full & WIFI_FEATURE_P2P) | + (feature_set_full & WIFI_FEATURE_D2AP_RTT) | + (feature_set_full & WIFI_FEATURE_D2D_RTT) | + (feature_set_full & WIFI_FEATURE_EPR); + + ret[2] = (feature_set_full & WIFI_FEATURE_INFRA) | + (feature_set_full & WIFI_FEATURE_INFRA_5G) | + (feature_set_full & WIFI_FEATURE_NAN) | + (feature_set_full & WIFI_FEATURE_D2D_RTT) | + (feature_set_full & WIFI_FEATURE_D2AP_RTT) | + (feature_set_full & WIFI_FEATURE_TDLS) | + (feature_set_full & WIFI_FEATURE_TDLS_OFFCHANNEL) | + (feature_set_full & WIFI_FEATURE_EPR); + *num = MAX_FEATURE_SET_CONCURRRENT_GROUPS; + + return ret; +} + +static int rtw_cfgvendor_get_feature_set(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + int reply; + + reply = rtw_dev_get_feature_set(wdev_to_ndev(wdev)); + + err = rtw_cfgvendor_send_cmd_reply(wiphy, wdev_to_ndev(wdev), &reply, sizeof(int)); + + if (unlikely(err)) + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Vendor Command reply failed ret:%d \n" + , FUNC_NDEV_ARG(wdev_to_ndev(wdev)), err); + + return err; +} + +static int rtw_cfgvendor_get_feature_set_matrix(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct sk_buff *skb; + int *reply; + int num, mem_needed, i; + + reply = rtw_dev_get_feature_set_matrix(wdev_to_ndev(wdev), &num); + + if (!reply) { + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Could not get feature list matrix\n" + , FUNC_NDEV_ARG(wdev_to_ndev(wdev))); + err = -EINVAL; + return err; + } + + mem_needed = VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * num) + + ATTRIBUTE_U32_LEN; + + /* Alloc the SKB for vendor_event */ + skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); + if (unlikely(!skb)) { + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(wdev_to_ndev(wdev))); + err = -ENOMEM; + goto exit; + } + + nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, num); + for (i = 0; i < num; i++) { + nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, reply[i]); + } + + err = rtw_cfg80211_vendor_cmd_reply(skb); + + if (unlikely(err)) + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Vendor Command reply failed ret:%d \n" + , FUNC_NDEV_ARG(wdev_to_ndev(wdev)), err); +exit: + rtw_mfree((u8*)reply, sizeof(int)*num); + return err; +} + +#if defined(GSCAN_SUPPORT) && 0 +int wl_cfgvendor_send_hotlist_event(struct wiphy *wiphy, + struct net_device *dev, void *data, int len, wl_vendor_event_t event) +{ + u16 kflags; + const void *ptr; + struct sk_buff *skb; + int malloc_len, total, iter_cnt_to_send, cnt; + gscan_results_cache_t *cache = (gscan_results_cache_t *)data; + + total = len/sizeof(wifi_gscan_result_t); + while (total > 0) { + malloc_len = (total * sizeof(wifi_gscan_result_t)) + VENDOR_DATA_OVERHEAD; + if (malloc_len > NLMSG_DEFAULT_SIZE) { + malloc_len = NLMSG_DEFAULT_SIZE; + } + iter_cnt_to_send = + (malloc_len - VENDOR_DATA_OVERHEAD)/sizeof(wifi_gscan_result_t); + total = total - iter_cnt_to_send; + + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + + /* Alloc the SKB for vendor_event */ + skb = rtw_cfg80211_vendor_event_alloc(wiphy, malloc_len, event, kflags); + if (!skb) { + WL_ERR(("skb alloc failed")); + return -ENOMEM; + } + + while (cache && iter_cnt_to_send) { + ptr = (const void *) &cache->results[cache->tot_consumed]; + + if (iter_cnt_to_send < (cache->tot_count - cache->tot_consumed)) + cnt = iter_cnt_to_send; + else + cnt = (cache->tot_count - cache->tot_consumed); + + iter_cnt_to_send -= cnt; + cache->tot_consumed += cnt; + /* Push the data to the skb */ + nla_append(skb, cnt * sizeof(wifi_gscan_result_t), ptr); + if (cache->tot_consumed == cache->tot_count) + cache = cache->next; + + } + + rtw_cfg80211_vendor_event(skb, kflags); + } + + return 0; +} + + +static int wl_cfgvendor_gscan_get_capabilities(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + dhd_pno_gscan_capabilities_t *reply = NULL; + uint32 reply_len = 0; + + + reply = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GET_CAPABILITIES, NULL, &reply_len); + if (!reply) { + WL_ERR(("Could not get capabilities\n")); + err = -EINVAL; + return err; + } + + err = rtw_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + reply, reply_len); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + + kfree(reply); + return err; +} + +static int wl_cfgvendor_gscan_get_channel_list(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0, type, band; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + uint16 *reply = NULL; + uint32 reply_len = 0, num_channels, mem_needed; + struct sk_buff *skb; + + type = nla_type(data); + + if (type == GSCAN_ATTRIBUTE_BAND) { + band = nla_get_u32(data); + } else { + return -1; + } + + reply = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GET_CHANNEL_LIST, &band, &reply_len); + + if (!reply) { + WL_ERR(("Could not get channel list\n")); + err = -EINVAL; + return err; + } + num_channels = reply_len/ sizeof(uint32); + mem_needed = reply_len + VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * 2); + + /* Alloc the SKB for vendor_event */ + skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); + if (unlikely(!skb)) { + WL_ERR(("skb alloc failed")); + err = -ENOMEM; + goto exit; + } + + nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_CHANNELS, num_channels); + nla_put(skb, GSCAN_ATTRIBUTE_CHANNEL_LIST, reply_len, reply); + + err = rtw_cfg80211_vendor_cmd_reply(skb); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); +exit: + kfree(reply); + return err; +} + +static int wl_cfgvendor_gscan_get_batch_results(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_results_cache_t *results, *iter; + uint32 reply_len, complete = 0, num_results_iter; + int32 mem_needed; + wifi_gscan_result_t *ptr; + uint16 num_scan_ids, num_results; + struct sk_buff *skb; + struct nlattr *scan_hdr; + + dhd_dev_wait_batch_results_complete(bcmcfg_to_prmry_ndev(cfg)); + dhd_dev_pno_lock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + results = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GET_BATCH_RESULTS, NULL, &reply_len); + + if (!results) { + WL_ERR(("No results to send %d\n", err)); + err = rtw_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + results, 0); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + return err; + } + num_scan_ids = reply_len & 0xFFFF; + num_results = (reply_len & 0xFFFF0000) >> 16; + mem_needed = (num_results * sizeof(wifi_gscan_result_t)) + + (num_scan_ids * GSCAN_BATCH_RESULT_HDR_LEN) + + VENDOR_REPLY_OVERHEAD + SCAN_RESULTS_COMPLETE_FLAG_LEN; + + if (mem_needed > (int32)NLMSG_DEFAULT_SIZE) { + mem_needed = (int32)NLMSG_DEFAULT_SIZE; + complete = 0; + } else { + complete = 1; + } + + WL_TRACE(("complete %d mem_needed %d max_mem %d\n", complete, mem_needed, + (int)NLMSG_DEFAULT_SIZE)); + /* Alloc the SKB for vendor_event */ + skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); + if (unlikely(!skb)) { + WL_ERR(("skb alloc failed")); + dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + return -ENOMEM; + } + iter = results; + + nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, complete); + + mem_needed = mem_needed - (SCAN_RESULTS_COMPLETE_FLAG_LEN + VENDOR_REPLY_OVERHEAD); + + while (iter && ((mem_needed - GSCAN_BATCH_RESULT_HDR_LEN) > 0)) { + scan_hdr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); + nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_ID, iter->scan_id); + nla_put_u8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, iter->flag); + num_results_iter = + (mem_needed - GSCAN_BATCH_RESULT_HDR_LEN)/sizeof(wifi_gscan_result_t); + + if ((iter->tot_count - iter->tot_consumed) < num_results_iter) + num_results_iter = iter->tot_count - iter->tot_consumed; + + nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num_results_iter); + if (num_results_iter) { + ptr = &iter->results[iter->tot_consumed]; + iter->tot_consumed += num_results_iter; + nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, + num_results_iter * sizeof(wifi_gscan_result_t), ptr); + } + nla_nest_end(skb, scan_hdr); + mem_needed -= GSCAN_BATCH_RESULT_HDR_LEN + + (num_results_iter * sizeof(wifi_gscan_result_t)); + iter = iter->next; + } + + dhd_dev_gscan_batch_cache_cleanup(bcmcfg_to_prmry_ndev(cfg)); + dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + + return rtw_cfg80211_vendor_cmd_reply(skb); +} + +static int wl_cfgvendor_initiate_gscan(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int type, tmp = len; + int run = 0xFF; + int flush = 0; + const struct nlattr *iter; + + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + if (type == GSCAN_ATTRIBUTE_ENABLE_FEATURE) + run = nla_get_u32(iter); + else if (type == GSCAN_ATTRIBUTE_FLUSH_FEATURE) + flush = nla_get_u32(iter); + } + + if (run != 0xFF) { + err = dhd_dev_pno_run_gscan(bcmcfg_to_prmry_ndev(cfg), run, flush); + + if (unlikely(err)) + WL_ERR(("Could not run gscan:%d \n", err)); + return err; + } else { + return -1; + } + + +} + +static int wl_cfgvendor_enable_full_scan_result(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int type; + bool real_time = FALSE; + + type = nla_type(data); + + if (type == GSCAN_ATTRIBUTE_ENABLE_FULL_SCAN_RESULTS) { + real_time = nla_get_u32(data); + + err = dhd_dev_pno_enable_full_scan_result(bcmcfg_to_prmry_ndev(cfg), real_time); + + if (unlikely(err)) + WL_ERR(("Could not run gscan:%d \n", err)); + + } else { + err = -1; + } + + return err; +} + +static int wl_cfgvendor_set_scan_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_scan_params_t *scan_param; + int j = 0; + int type, tmp, tmp1, tmp2, k = 0; + const struct nlattr *iter, *iter1, *iter2; + struct dhd_pno_gscan_channel_bucket *ch_bucket; + + scan_param = kzalloc(sizeof(gscan_scan_params_t), GFP_KERNEL); + if (!scan_param) { + WL_ERR(("Could not set GSCAN scan cfg, mem alloc failure\n")); + err = -EINVAL; + return err; + + } + + scan_param->scan_fr = PNO_SCAN_MIN_FW_SEC; + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + + if (j >= GSCAN_MAX_CH_BUCKETS) + break; + + switch (type) { + case GSCAN_ATTRIBUTE_BASE_PERIOD: + scan_param->scan_fr = nla_get_u32(iter)/1000; + break; + case GSCAN_ATTRIBUTE_NUM_BUCKETS: + scan_param->nchannel_buckets = nla_get_u32(iter); + break; + case GSCAN_ATTRIBUTE_CH_BUCKET_1: + case GSCAN_ATTRIBUTE_CH_BUCKET_2: + case GSCAN_ATTRIBUTE_CH_BUCKET_3: + case GSCAN_ATTRIBUTE_CH_BUCKET_4: + case GSCAN_ATTRIBUTE_CH_BUCKET_5: + case GSCAN_ATTRIBUTE_CH_BUCKET_6: + case GSCAN_ATTRIBUTE_CH_BUCKET_7: + nla_for_each_nested(iter1, iter, tmp1) { + type = nla_type(iter1); + ch_bucket = + scan_param->channel_bucket; + + switch (type) { + case GSCAN_ATTRIBUTE_BUCKET_ID: + break; + case GSCAN_ATTRIBUTE_BUCKET_PERIOD: + ch_bucket[j].bucket_freq_multiple = + nla_get_u32(iter1)/1000; + break; + case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: + ch_bucket[j].num_channels = + nla_get_u32(iter1); + break; + case GSCAN_ATTRIBUTE_BUCKET_CHANNELS: + nla_for_each_nested(iter2, iter1, tmp2) { + if (k >= PFN_SWC_RSSI_WINDOW_MAX) + break; + ch_bucket[j].chan_list[k] = + nla_get_u32(iter2); + k++; + } + k = 0; + break; + case GSCAN_ATTRIBUTE_BUCKETS_BAND: + ch_bucket[j].band = (uint16) + nla_get_u32(iter1); + break; + case GSCAN_ATTRIBUTE_REPORT_EVENTS: + ch_bucket[j].report_flag = (uint8) + nla_get_u32(iter1); + break; + } + } + j++; + break; + } + } + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_SCAN_CFG_ID, scan_param, 0) < 0) { + WL_ERR(("Could not set GSCAN scan cfg\n")); + err = -EINVAL; + } + + kfree(scan_param); + return err; + +} + +static int wl_cfgvendor_hotlist_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_hotlist_scan_params_t *hotlist_params; + int tmp, tmp1, tmp2, type, j = 0, dummy; + const struct nlattr *outer, *inner, *iter; + uint8 flush = 0; + struct bssid_t *pbssid; + + hotlist_params = (gscan_hotlist_scan_params_t *)kzalloc(len, GFP_KERNEL); + if (!hotlist_params) { + WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len)); + return -1; + } + + hotlist_params->lost_ap_window = GSCAN_LOST_AP_WINDOW_DEFAULT; + + nla_for_each_attr(iter, data, len, tmp2) { + type = nla_type(iter); + switch (type) { + case GSCAN_ATTRIBUTE_HOTLIST_BSSIDS: + pbssid = hotlist_params->bssid; + nla_for_each_nested(outer, iter, tmp) { + nla_for_each_nested(inner, outer, tmp1) { + type = nla_type(inner); + + switch (type) { + case GSCAN_ATTRIBUTE_BSSID: + memcpy(&(pbssid[j].macaddr), + nla_data(inner), ETHER_ADDR_LEN); + break; + case GSCAN_ATTRIBUTE_RSSI_LOW: + pbssid[j].rssi_reporting_threshold = + (int8) nla_get_u8(inner); + break; + case GSCAN_ATTRIBUTE_RSSI_HIGH: + dummy = (int8) nla_get_u8(inner); + break; + } + } + j++; + } + hotlist_params->nbssid = j; + break; + case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: + flush = nla_get_u8(iter); + break; + case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: + hotlist_params->lost_ap_window = nla_get_u32(iter); + break; + } + + } + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GEOFENCE_SCAN_CFG_ID, hotlist_params, flush) < 0) { + WL_ERR(("Could not set GSCAN HOTLIST cfg\n")); + err = -EINVAL; + goto exit; + } +exit: + kfree(hotlist_params); + return err; +} +static int wl_cfgvendor_set_batch_scan_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0, tmp, type; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_batch_params_t batch_param; + const struct nlattr *iter; + + batch_param.mscan = batch_param.bestn = 0; + batch_param.buffer_threshold = GSCAN_BATCH_NO_THR_SET; + + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + + switch (type) { + case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: + batch_param.bestn = nla_get_u32(iter); + break; + case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: + batch_param.mscan = nla_get_u32(iter); + break; + case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: + batch_param.buffer_threshold = nla_get_u32(iter); + break; + } + } + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_BATCH_SCAN_CFG_ID, &batch_param, 0) < 0) { + WL_ERR(("Could not set batch cfg\n")); + err = -EINVAL; + return err; + } + + return err; +} + +static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_swc_params_t *significant_params; + int tmp, tmp1, tmp2, type, j = 0; + const struct nlattr *outer, *inner, *iter; + uint8 flush = 0; + wl_pfn_significant_bssid_t *pbssid; + + significant_params = (gscan_swc_params_t *) kzalloc(len, GFP_KERNEL); + if (!significant_params) { + WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len)); + return -1; + } + + + nla_for_each_attr(iter, data, len, tmp2) { + type = nla_type(iter); + + switch (type) { + case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: + flush = nla_get_u8(iter); + break; + case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: + significant_params->rssi_window = nla_get_u16(iter); + break; + case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: + significant_params->lost_ap_window = nla_get_u16(iter); + break; + case GSCAN_ATTRIBUTE_MIN_BREACHING: + significant_params->swc_threshold = nla_get_u16(iter); + break; + case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS: + pbssid = significant_params->bssid_elem_list; + nla_for_each_nested(outer, iter, tmp) { + nla_for_each_nested(inner, outer, tmp1) { + switch (nla_type(inner)) { + case GSCAN_ATTRIBUTE_BSSID: + memcpy(&(pbssid[j].macaddr), + nla_data(inner), + ETHER_ADDR_LEN); + break; + case GSCAN_ATTRIBUTE_RSSI_HIGH: + pbssid[j].rssi_high_threshold = + (int8) nla_get_u8(inner); + break; + case GSCAN_ATTRIBUTE_RSSI_LOW: + pbssid[j].rssi_low_threshold = + (int8) nla_get_u8(inner); + break; + } + } + j++; + } + break; + } + } + significant_params->nbssid = j; + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_SIGNIFICANT_SCAN_CFG_ID, significant_params, flush) < 0) { + WL_ERR(("Could not set GSCAN significant cfg\n")); + err = -EINVAL; + goto exit; + } +exit: + kfree(significant_params); + return err; +} +#endif /* GSCAN_SUPPORT */ + +#if defined(RTT_SUPPORT) && 0 +void wl_cfgvendor_rtt_evt(void *ctx, void *rtt_data) +{ + struct wireless_dev *wdev = (struct wireless_dev *)ctx; + struct wiphy *wiphy; + struct sk_buff *skb; + uint32 tot_len = NLMSG_DEFAULT_SIZE, entry_len = 0; + gfp_t kflags; + rtt_report_t *rtt_report = NULL; + rtt_result_t *rtt_result = NULL; + struct list_head *rtt_list; + wiphy = wdev->wiphy; + + WL_DBG(("In\n")); + /* Push the data to the skb */ + if (!rtt_data) { + WL_ERR(("rtt_data is NULL\n")); + goto exit; + } + rtt_list = (struct list_head *)rtt_data; + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + /* Alloc the SKB for vendor_event */ + skb = rtw_cfg80211_vendor_event_alloc(wiphy, tot_len, GOOGLE_RTT_COMPLETE_EVENT, kflags); + if (!skb) { + WL_ERR(("skb alloc failed")); + goto exit; + } + /* fill in the rtt results on each entry */ + list_for_each_entry(rtt_result, rtt_list, list) { + entry_len = 0; + if (rtt_result->TOF_type == TOF_TYPE_ONE_WAY) { + entry_len = sizeof(rtt_report_t); + rtt_report = kzalloc(entry_len, kflags); + if (!rtt_report) { + WL_ERR(("rtt_report alloc failed")); + goto exit; + } + rtt_report->addr = rtt_result->peer_mac; + rtt_report->num_measurement = 1; /* ONE SHOT */ + rtt_report->status = rtt_result->err_code; + rtt_report->type = (rtt_result->TOF_type == TOF_TYPE_ONE_WAY) ? RTT_ONE_WAY: RTT_TWO_WAY; + rtt_report->peer = rtt_result->target_info->peer; + rtt_report->channel = rtt_result->target_info->channel; + rtt_report->rssi = rtt_result->avg_rssi; + /* tx_rate */ + rtt_report->tx_rate = rtt_result->tx_rate; + /* RTT */ + rtt_report->rtt = rtt_result->meanrtt; + rtt_report->rtt_sd = rtt_result->sdrtt; + /* convert to centi meter */ + if (rtt_result->distance != 0xffffffff) + rtt_report->distance = (rtt_result->distance >> 2) * 25; + else /* invalid distance */ + rtt_report->distance = -1; + + rtt_report->ts = rtt_result->ts; + nla_append(skb, entry_len, rtt_report); + kfree(rtt_report); + } + } + rtw_cfg80211_vendor_event(skb, kflags); +exit: + return; +} + +static int wl_cfgvendor_rtt_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) { + int err = 0, rem, rem1, rem2, type; + rtt_config_params_t rtt_param; + rtt_target_info_t* rtt_target = NULL; + const struct nlattr *iter, *iter1, *iter2; + int8 eabuf[ETHER_ADDR_STR_LEN]; + int8 chanbuf[CHANSPEC_STR_LEN]; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + + WL_DBG(("In\n")); + err = dhd_dev_rtt_register_noti_callback(wdev->netdev, wdev, wl_cfgvendor_rtt_evt); + if (err < 0) { + WL_ERR(("failed to register rtt_noti_callback\n")); + goto exit; + } + memset(&rtt_param, 0, sizeof(rtt_param)); + nla_for_each_attr(iter, data, len, rem) { + type = nla_type(iter); + switch (type) { + case RTT_ATTRIBUTE_TARGET_CNT: + rtt_param.rtt_target_cnt = nla_get_u8(iter); + if (rtt_param.rtt_target_cnt > RTT_MAX_TARGET_CNT) { + WL_ERR(("exceed max target count : %d\n", + rtt_param.rtt_target_cnt)); + err = BCME_RANGE; + } + break; + case RTT_ATTRIBUTE_TARGET_INFO: + rtt_target = rtt_param.target_info; + nla_for_each_nested(iter1, iter, rem1) { + nla_for_each_nested(iter2, iter1, rem2) { + type = nla_type(iter2); + switch (type) { + case RTT_ATTRIBUTE_TARGET_MAC: + memcpy(&rtt_target->addr, nla_data(iter2), ETHER_ADDR_LEN); + break; + case RTT_ATTRIBUTE_TARGET_TYPE: + rtt_target->type = nla_get_u8(iter2); + break; + case RTT_ATTRIBUTE_TARGET_PEER: + rtt_target->peer= nla_get_u8(iter2); + break; + case RTT_ATTRIBUTE_TARGET_CHAN: + memcpy(&rtt_target->channel, nla_data(iter2), + sizeof(rtt_target->channel)); + break; + case RTT_ATTRIBUTE_TARGET_MODE: + rtt_target->continuous = nla_get_u8(iter2); + break; + case RTT_ATTRIBUTE_TARGET_INTERVAL: + rtt_target->interval = nla_get_u32(iter2); + break; + case RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT: + rtt_target->measure_cnt = nla_get_u32(iter2); + break; + case RTT_ATTRIBUTE_TARGET_NUM_PKT: + rtt_target->ftm_cnt = nla_get_u32(iter2); + break; + case RTT_ATTRIBUTE_TARGET_NUM_RETRY: + rtt_target->retry_cnt = nla_get_u32(iter2); + } + } + /* convert to chanspec value */ + rtt_target->chanspec = dhd_rtt_convert_to_chspec(rtt_target->channel); + if (rtt_target->chanspec == 0) { + WL_ERR(("Channel is not valid \n")); + goto exit; + } + WL_INFORM(("Target addr %s, Channel : %s for RTT \n", + bcm_ether_ntoa((const struct ether_addr *)&rtt_target->addr, eabuf), + wf_chspec_ntoa(rtt_target->chanspec, chanbuf))); + rtt_target++; + } + break; + } + } + WL_DBG(("leave :target_cnt : %d\n", rtt_param.rtt_target_cnt)); + if (dhd_dev_rtt_set_cfg(bcmcfg_to_prmry_ndev(cfg), &rtt_param) < 0) { + WL_ERR(("Could not set RTT configuration\n")); + err = -EINVAL; + } +exit: + return err; +} + +static int wl_cfgvendor_rtt_cancel_config(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) +{ + int err = 0, rem, type, target_cnt = 0; + const struct nlattr *iter; + struct ether_addr *mac_list = NULL, *mac_addr = NULL; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + + nla_for_each_attr(iter, data, len, rem) { + type = nla_type(iter); + switch (type) { + case RTT_ATTRIBUTE_TARGET_CNT: + target_cnt = nla_get_u8(iter); + mac_list = (struct ether_addr *)kzalloc(target_cnt * ETHER_ADDR_LEN , GFP_KERNEL); + if (mac_list == NULL) { + WL_ERR(("failed to allocate mem for mac list\n")); + goto exit; + } + mac_addr = &mac_list[0]; + break; + case RTT_ATTRIBUTE_TARGET_MAC: + if (mac_addr) + memcpy(mac_addr++, nla_data(iter), ETHER_ADDR_LEN); + else { + WL_ERR(("mac_list is NULL\n")); + goto exit; + } + break; + } + if (dhd_dev_rtt_cancel_cfg(bcmcfg_to_prmry_ndev(cfg), mac_list, target_cnt) < 0) { + WL_ERR(("Could not cancel RTT configuration\n")); + err = -EINVAL; + goto exit; + } + } +exit: + if (mac_list) + kfree(mac_list); + return err; +} +static int wl_cfgvendor_rtt_get_capability(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + rtt_capabilities_t capability; + + err = dhd_dev_rtt_capability(bcmcfg_to_prmry_ndev(cfg), &capability); + if (unlikely(err)) { + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + goto exit; + } + err = rtw_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + &capability, sizeof(capability)); + + if (unlikely(err)) { + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + } +exit: + return err; +} + +#endif /* RTT_SUPPORT */ +static int wl_cfgvendor_priv_string_handler(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + u8 resp[1] = {'\0'}; + + DBG_871X_LEVEL(_drv_always_, FUNC_NDEV_FMT" %s\n", FUNC_NDEV_ARG(wdev_to_ndev(wdev)), (char*)data); + err = rtw_cfgvendor_send_cmd_reply(wiphy, wdev_to_ndev(wdev), resp, 1); + if (unlikely(err)) + DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT"Vendor Command reply failed ret:%d \n" + , FUNC_NDEV_ARG(wdev_to_ndev(wdev)), err); + + return err; +#if 0 + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int err = 0; + int data_len = 0; + + bzero(cfg->ioctl_buf, WLC_IOCTL_MAXLEN); + + if (strncmp((char *)data, BRCM_VENDOR_SCMD_CAPA, strlen(BRCM_VENDOR_SCMD_CAPA)) == 0) { + err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "cap", NULL, 0, + cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync); + if (unlikely(err)) { + WL_ERR(("error (%d)\n", err)); + return err; + } + data_len = strlen(cfg->ioctl_buf); + cfg->ioctl_buf[data_len] = '\0'; + } + + err = rtw_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + cfg->ioctl_buf, data_len+1); + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + else + WL_INFORM(("Vendor Command reply sent successfully!\n")); + + return err; +#endif +} + +static const struct wiphy_vendor_command rtw_vendor_cmds [] = { + { + { + .vendor_id = OUI_BRCM, + .subcmd = BRCM_VENDOR_SCMD_PRIV_STR + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_priv_string_handler + }, +#if defined(GSCAN_SUPPORT) && 0 + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_gscan_get_capabilities + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_set_scan_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_set_batch_scan_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_initiate_gscan + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_enable_full_scan_result + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_HOTLIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_hotlist_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_significant_change_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_gscan_get_batch_results + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_gscan_get_channel_list + }, +#endif /* GSCAN_SUPPORT */ +#if defined(RTT_SUPPORT) && 0 + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = RTT_SUBCMD_SET_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_rtt_set_config + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = RTT_SUBCMD_CANCEL_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_rtt_cancel_config + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = RTT_SUBCMD_GETCAPABILITY + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_rtt_get_capability + }, +#endif /* RTT_SUPPORT */ + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = rtw_cfgvendor_get_feature_set + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = rtw_cfgvendor_get_feature_set_matrix + } +}; + +static const struct nl80211_vendor_cmd_info rtw_vendor_events [] = { + { OUI_BRCM, BRCM_VENDOR_EVENT_UNSPEC }, + { OUI_BRCM, BRCM_VENDOR_EVENT_PRIV_STR }, +#if defined(GSCAN_SUPPORT) && 0 + { OUI_GOOGLE, GOOGLE_GSCAN_SIGNIFICANT_EVENT }, + { OUI_GOOGLE, GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT }, + { OUI_GOOGLE, GOOGLE_GSCAN_BATCH_SCAN_EVENT }, + { OUI_GOOGLE, GOOGLE_SCAN_FULL_RESULTS_EVENT }, +#endif /* GSCAN_SUPPORT */ +#if defined(RTT_SUPPORT) && 0 + { OUI_GOOGLE, GOOGLE_RTT_COMPLETE_EVENT }, +#endif /* RTT_SUPPORT */ +#if defined(GSCAN_SUPPORT) && 0 + { OUI_GOOGLE, GOOGLE_SCAN_COMPLETE_EVENT }, + { OUI_GOOGLE, GOOGLE_GSCAN_GEOFENCE_LOST_EVENT } +#endif /* GSCAN_SUPPORT */ +}; + +int rtw_cfgvendor_attach(struct wiphy *wiphy) +{ + + DBG_871X("Register RTW cfg80211 vendor cmd(0x%x) interface \n", NL80211_CMD_VENDOR); + + wiphy->vendor_commands = rtw_vendor_cmds; + wiphy->n_vendor_commands = ARRAY_SIZE(rtw_vendor_cmds); + wiphy->vendor_events = rtw_vendor_events; + wiphy->n_vendor_events = ARRAY_SIZE(rtw_vendor_events); + + return 0; +} + +int rtw_cfgvendor_detach(struct wiphy *wiphy) +{ + DBG_871X("Vendor: Unregister RTW cfg80211 vendor interface \n"); + + wiphy->vendor_commands = NULL; + wiphy->vendor_events = NULL; + wiphy->n_vendor_commands = 0; + wiphy->n_vendor_events = 0; + + return 0; +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) */ + +#endif /* CONFIG_IOCTL_CFG80211 */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_cfgvendor.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_cfgvendor.h new file mode 100755 index 000000000000..7c349e79daa2 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_cfgvendor.h @@ -0,0 +1,246 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2014 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef _RTW_CFGVENDOR_H_ +#define _RTW_CFGVENDOR_H_ + +#define OUI_BRCM 0x001018 +#define OUI_GOOGLE 0x001A11 +#define BRCM_VENDOR_SUBCMD_PRIV_STR 1 +#define ATTRIBUTE_U32_LEN (NLA_HDRLEN + 4) +#define VENDOR_ID_OVERHEAD ATTRIBUTE_U32_LEN +#define VENDOR_SUBCMD_OVERHEAD ATTRIBUTE_U32_LEN +#define VENDOR_DATA_OVERHEAD (NLA_HDRLEN) + +#define SCAN_RESULTS_COMPLETE_FLAG_LEN ATTRIBUTE_U32_LEN +#define SCAN_INDEX_HDR_LEN (NLA_HDRLEN) +#define SCAN_ID_HDR_LEN ATTRIBUTE_U32_LEN +#define SCAN_FLAGS_HDR_LEN ATTRIBUTE_U32_LEN +#define GSCAN_NUM_RESULTS_HDR_LEN ATTRIBUTE_U32_LEN +#define GSCAN_RESULTS_HDR_LEN (NLA_HDRLEN) +#define GSCAN_BATCH_RESULT_HDR_LEN (SCAN_INDEX_HDR_LEN + SCAN_ID_HDR_LEN + \ + SCAN_FLAGS_HDR_LEN + \ + GSCAN_NUM_RESULTS_HDR_LEN + \ + GSCAN_RESULTS_HDR_LEN) + +#define VENDOR_REPLY_OVERHEAD (VENDOR_ID_OVERHEAD + \ + VENDOR_SUBCMD_OVERHEAD + \ + VENDOR_DATA_OVERHEAD) +typedef enum { + /* don't use 0 as a valid subcommand */ + VENDOR_NL80211_SUBCMD_UNSPECIFIED, + + /* define all vendor startup commands between 0x0 and 0x0FFF */ + VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001, + VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF, + + /* define all GScan related commands between 0x1000 and 0x10FF */ + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, + + /* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */ + ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100, + ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x11FF, + + /* define all RTT related commands between 0x1100 and 0x11FF */ + ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, + ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, + + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, + + ANDROID_NL80211_SUBCMD_TDLS_RANGE_START = 0x1300, + ANDROID_NL80211_SUBCMD_TDLS_RANGE_END = 0x13FF, + /* This is reserved for future usage */ + +} ANDROID_VENDOR_SUB_COMMAND; + +enum wl_vendor_subcmd { + BRCM_VENDOR_SCMD_UNSPEC, + BRCM_VENDOR_SCMD_PRIV_STR, + GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, + GSCAN_SUBCMD_SET_CONFIG, + GSCAN_SUBCMD_SET_SCAN_CONFIG, + GSCAN_SUBCMD_ENABLE_GSCAN, + GSCAN_SUBCMD_GET_SCAN_RESULTS, + GSCAN_SUBCMD_SCAN_RESULTS, + GSCAN_SUBCMD_SET_HOTLIST, + GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, + GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, + GSCAN_SUBCMD_GET_CHANNEL_LIST, + ANDR_WIFI_SUBCMD_GET_FEATURE_SET, + ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, + RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, + RTT_SUBCMD_CANCEL_CONFIG, + RTT_SUBCMD_GETCAPABILITY, + /* Add more sub commands here */ + VENDOR_SUBCMD_MAX +}; + +enum gscan_attributes { + GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, + GSCAN_ATTRIBUTE_BASE_PERIOD, + GSCAN_ATTRIBUTE_BUCKETS_BAND, + GSCAN_ATTRIBUTE_BUCKET_ID, + GSCAN_ATTRIBUTE_BUCKET_PERIOD, + GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, + GSCAN_ATTRIBUTE_BUCKET_CHANNELS, + GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, + GSCAN_ATTRIBUTE_REPORT_THRESHOLD, + GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, + GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND, + + GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, + GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, + GSCAN_ATTRIBUTE_FLUSH_FEATURE, + GSCAN_ATTRIBUTE_ENABLE_FULL_SCAN_RESULTS, + GSCAN_ATTRIBUTE_REPORT_EVENTS, + /* remaining reserved for additional attributes */ + GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, + GSCAN_ATTRIBUTE_FLUSH_RESULTS, + GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ + GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ + GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ + GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ + GSCAN_ATTRIBUTE_NUM_CHANNELS, + GSCAN_ATTRIBUTE_CHANNEL_LIST, + + /* remaining reserved for additional attributes */ + + GSCAN_ATTRIBUTE_SSID = 40, + GSCAN_ATTRIBUTE_BSSID, + GSCAN_ATTRIBUTE_CHANNEL, + GSCAN_ATTRIBUTE_RSSI, + GSCAN_ATTRIBUTE_TIMESTAMP, + GSCAN_ATTRIBUTE_RTT, + GSCAN_ATTRIBUTE_RTTSD, + + /* remaining reserved for additional attributes */ + + GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, + GSCAN_ATTRIBUTE_RSSI_LOW, + GSCAN_ATTRIBUTE_RSSI_HIGH, + GSCAN_ATTRIBUTE_HOSTLIST_BSSID_ELEM, + GSCAN_ATTRIBUTE_HOTLIST_FLUSH, + + /* remaining reserved for additional attributes */ + GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, + GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, + GSCAN_ATTRIBUTE_MIN_BREACHING, + GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, + GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, + GSCAN_ATTRIBUTE_MAX +}; + +enum gscan_bucket_attributes { + GSCAN_ATTRIBUTE_CH_BUCKET_1, + GSCAN_ATTRIBUTE_CH_BUCKET_2, + GSCAN_ATTRIBUTE_CH_BUCKET_3, + GSCAN_ATTRIBUTE_CH_BUCKET_4, + GSCAN_ATTRIBUTE_CH_BUCKET_5, + GSCAN_ATTRIBUTE_CH_BUCKET_6, + GSCAN_ATTRIBUTE_CH_BUCKET_7 +}; + +enum gscan_ch_attributes { + GSCAN_ATTRIBUTE_CH_ID_1, + GSCAN_ATTRIBUTE_CH_ID_2, + GSCAN_ATTRIBUTE_CH_ID_3, + GSCAN_ATTRIBUTE_CH_ID_4, + GSCAN_ATTRIBUTE_CH_ID_5, + GSCAN_ATTRIBUTE_CH_ID_6, + GSCAN_ATTRIBUTE_CH_ID_7 +}; + +enum rtt_attributes { + RTT_ATTRIBUTE_TARGET_CNT, + RTT_ATTRIBUTE_TARGET_INFO, + RTT_ATTRIBUTE_TARGET_MAC, + RTT_ATTRIBUTE_TARGET_TYPE, + RTT_ATTRIBUTE_TARGET_PEER, + RTT_ATTRIBUTE_TARGET_CHAN, + RTT_ATTRIBUTE_TARGET_MODE, + RTT_ATTRIBUTE_TARGET_INTERVAL, + RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT, + RTT_ATTRIBUTE_TARGET_NUM_PKT, + RTT_ATTRIBUTE_TARGET_NUM_RETRY +}; + +typedef enum wl_vendor_event { + BRCM_VENDOR_EVENT_UNSPEC, + BRCM_VENDOR_EVENT_PRIV_STR, + GOOGLE_GSCAN_SIGNIFICANT_EVENT, + GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT, + GOOGLE_GSCAN_BATCH_SCAN_EVENT, + GOOGLE_SCAN_FULL_RESULTS_EVENT, + GOOGLE_RTT_COMPLETE_EVENT, + GOOGLE_SCAN_COMPLETE_EVENT, + GOOGLE_GSCAN_GEOFENCE_LOST_EVENT +} wl_vendor_event_t; + +enum andr_wifi_feature_set_attr { + ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, + ANDR_WIFI_ATTRIBUTE_FEATURE_SET +}; + +typedef enum wl_vendor_gscan_attribute { + ATTR_START_GSCAN, + ATTR_STOP_GSCAN, + ATTR_SET_SCAN_BATCH_CFG_ID, /* set batch scan params */ + ATTR_SET_SCAN_GEOFENCE_CFG_ID, /* set list of bssids to track */ + ATTR_SET_SCAN_SIGNIFICANT_CFG_ID, /* set list of bssids, rssi threshold etc.. */ + ATTR_SET_SCAN_CFG_ID, /* set common scan config params here */ + ATTR_GET_GSCAN_CAPABILITIES_ID, + /* Add more sub commands here */ + ATTR_GSCAN_MAX +} wl_vendor_gscan_attribute_t; + +typedef enum gscan_batch_attribute { + ATTR_GSCAN_BATCH_BESTN, + ATTR_GSCAN_BATCH_MSCAN, + ATTR_GSCAN_BATCH_BUFFER_THRESHOLD +} gscan_batch_attribute_t; + +typedef enum gscan_geofence_attribute { + ATTR_GSCAN_NUM_HOTLIST_BSSID, + ATTR_GSCAN_HOTLIST_BSSID +} gscan_geofence_attribute_t; + +typedef enum gscan_complete_event { + WIFI_SCAN_BUFFER_FULL, + WIFI_SCAN_COMPLETE +} gscan_complete_event_t; + +/* Capture the BRCM_VENDOR_SUBCMD_PRIV_STRINGS* here */ +#define BRCM_VENDOR_SCMD_CAPA "cap" + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) +extern int rtw_cfgvendor_attach(struct wiphy *wiphy); +extern int rtw_cfgvendor_detach(struct wiphy *wiphy); +extern int rtw_cfgvendor_send_async_event(struct wiphy *wiphy, + struct net_device *dev, int event_id, const void *data, int len); +#if defined(GSCAN_SUPPORT) && 0 +extern int wl_cfgvendor_send_hotlist_event(struct wiphy *wiphy, + struct net_device *dev, void *data, int len, wl_vendor_event_t event); +#endif +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) */ + +#endif /* _RTW_CFGVENDOR_H_ */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.c index 039578642edf..c752173b69cd 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.c @@ -19,6 +19,7 @@ ******************************************************************************/ #include +#include #include "rtw_proc.h" #ifdef CONFIG_PROC_DEBUG @@ -69,9 +70,9 @@ inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct pro struct proc_dir_entry *entry; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) - entry = proc_create_data(name, S_IFREG|S_IRUGO, parent, fops, data); + entry = proc_create_data(name, S_IFREG|S_IRUGO|S_IWUGO, parent, fops, data); #else - entry = create_proc_entry(name, S_IFREG|S_IRUGO, parent); + entry = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUGO, parent); if (entry) { entry->data = data; entry->proc_fops = fops; @@ -261,14 +262,93 @@ static int proc_get_rf_reg_dump(struct seq_file *m, void *v) return 0; } -static int proc_get_linked_info_dump(struct seq_file *m, void *v) + + +//gpio setting +#ifdef CONFIG_GPIO_API +static ssize_t proc_set_config_gpio(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]={0}; + int num=0,gpio_pin=0,gpio_mode=0;//gpio_mode:0 input 1:output; + + if (count < 2) + return -EFAULT; + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + num =sscanf(tmp, "%d %d",&gpio_pin,&gpio_mode); + DBG_871X("num=%d gpio_pin=%d mode=%d\n",num,gpio_pin,gpio_mode); + padapter->pre_gpio_pin=gpio_pin; + + if(gpio_mode==0 || gpio_mode==1 ) + rtw_hal_config_gpio(padapter, gpio_pin,gpio_mode); + } + return count; + +} +static ssize_t proc_set_gpio_output_value(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]={0}; + int num=0,gpio_pin=0,pin_mode=0;//pin_mode: 1 high 0:low + + if (count < 2) + return -EFAULT; + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + num =sscanf(tmp, "%d %d",&gpio_pin,&pin_mode); + DBG_871X("num=%d gpio_pin=%d pin_high=%d\n",num,gpio_pin,pin_mode); + padapter->pre_gpio_pin=gpio_pin; + + if(pin_mode==0 || pin_mode==1 ) + rtw_hal_set_gpio_output_value(padapter, gpio_pin,pin_mode); + } + return count; +} +static int proc_get_gpio(struct seq_file *m, void *v) +{ + u8 gpioreturnvalue=0; struct net_device *dev = m->private; + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + if(!padapter) + return -EFAULT; + gpioreturnvalue = rtw_hal_get_gpio(padapter, padapter->pre_gpio_pin); + DBG_871X_SEL_NL(m, "get_gpio %d:%d \n",padapter->pre_gpio_pin ,gpioreturnvalue); + + return 0; + +} +static ssize_t proc_set_gpio(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]={0}; + int num=0,gpio_pin=0; - if(padapter) - DBG_871X_SEL_NL(m, "linked_info_dump :%s \n", (padapter->bLinkInfoDump)?"enable":"disable"); + if (count < 1) + return -EFAULT; + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + num =sscanf(tmp, "%d",&gpio_pin); + DBG_871X("num=%d gpio_pin=%d\n",num,gpio_pin); + padapter->pre_gpio_pin=gpio_pin; + + } + return count; +} +#endif + +static int proc_get_linked_info_dump(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + if(padapter) + DBG_871X_SEL_NL(m, "linked_info_dump :%s \n", (padapter->bLinkInfoDump)?"enable":"disable"); + return 0; } @@ -276,28 +356,40 @@ static ssize_t proc_set_linked_info_dump(struct file *file, const char __user *b { struct net_device *dev = data; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); - - char tmp[2]; - int mode=0; + + char tmp[32]={0}; + int mode=0,pre_mode=0; + int num=0; if (count < 1) return -EFAULT; - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + pre_mode=padapter->bLinkInfoDump; + DBG_871X("pre_mode=%d \n",pre_mode); - int num = sscanf(tmp, "%d ", &mode); + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + num =sscanf(tmp, "%d ", &mode); + DBG_871X("num=%d mode=%d\n",num,mode); - if( padapter ) + if(num!=1) { - //padapter->bLinkInfoDump = mode; - //DBG_871X("linked_info_dump =%s \n", (padapter->bLinkInfoDump)?"enable":"disable"); - linked_info_dump(padapter,mode); + DBG_871X("argument number is wrong\n"); + return -EFAULT; } - - } + if(mode==1 || (mode==0 && pre_mode==1) ) //not consider pwr_saving 0: + { + padapter->bLinkInfoDump = mode; + + } + else if( (mode==2 ) || (mode==0 && pre_mode==2))//consider power_saving + { + //DBG_871X("linked_info_dump =%s \n", (padapter->bLinkInfoDump)?"enable":"disable") + linked_info_dump(padapter,mode); + } + } return count; - } int proc_get_rx_info(struct seq_file *m, void *v) @@ -318,6 +410,15 @@ int proc_get_rx_info(struct seq_file *m, void *v) return 0; } +static int proc_get_mac_qinfo(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + rtw_hal_get_hwreg(adapter, HW_VAR_DUMP_MAC_QUEUE_INFO, (u8 *)m); + + return 0; +} ssize_t proc_reset_rx_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { @@ -339,6 +440,137 @@ ssize_t proc_reset_rx_info(struct file *file, const char __user *buffer, size_t return count; } +int proc_get_wifi_spec(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + DBG_871X_SEL_NL(m,"wifi_spec=%d\n",pregpriv->wifi_spec); + return 0; +} + +static int proc_get_chan_plan(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL_NL(m,"Channel plan=0x%02x\n",padapter->mlmepriv.ChannelPlan); + return 0; +} +static ssize_t proc_set_chan_plan(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct SetChannelPlan_param setChannelPlan_param; + + char tmp[32]; + u8 chan_plan = RT_CHANNEL_DOMAIN_REALTEK_DEFINE; + + if (!padapter) + return -EFAULT; + + if (count < 1) + { + DBG_871X("argument size is less than 1\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%hhx", &chan_plan); + + if (num != 1) { + DBG_871X("invalid read_reg parameter!\n"); + return count; + } + + } + setChannelPlan_param.channel_plan = chan_plan; + if( H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)&setChannelPlan_param) ) + return -EFAULT; + + return count; + +} + +static int proc_get_udpport(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct recv_priv *precvpriv = &(padapter->recvpriv); + + DBG_871X_SEL_NL(m,"%d\n",precvpriv->sink_udpport); + return 0; +} +static ssize_t proc_set_udpport(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct recv_priv *precvpriv = &(padapter->recvpriv); + int sink_udpport = 0; + char tmp[32]; + + + if (!padapter) + return -EFAULT; + + if (count < 1) + { + DBG_871X("argument size is less than 1\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%d", &sink_udpport); + + if (num != 1) { + DBG_871X("invalid input parameter number!\n"); + return count; + } + + } + precvpriv->sink_udpport = sink_udpport; + + return count; + +} + +static int proc_get_macid_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + u8 i; + + DBG_871X_SEL_NL(m, "max_num:%u\n", macid_ctl->num); + DBG_871X_SEL_NL(m, "\n"); + + DBG_871X_SEL_NL(m, "used:\n"); + dump_macid_map(m, &macid_ctl->used, macid_ctl->num); + DBG_871X_SEL_NL(m, "\n"); + + DBG_871X_SEL_NL(m, "%-3s %-3s %-4s %-4s" + "\n" + , "id", "bmc", "if_g", "ch_g" + ); + + for (i=0;inum;i++) { + if (rtw_macid_is_used(macid_ctl, i)) + DBG_871X_SEL_NL(m, "%3u %3u %4d %4d" + "\n" + , i + , rtw_macid_is_bmc(macid_ctl, i) + , rtw_macid_get_if_g(macid_ctl, i) + , rtw_macid_get_ch_g(macid_ctl, i) + ); + } + + return 0; +} + static int proc_get_cam(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -468,11 +700,14 @@ const struct rtw_proc_hdl adapter_proc_hdls [] = { {"adapter_state", proc_get_adapter_state, NULL}, {"trx_info", proc_get_trx_info, NULL}, {"rate_ctl", proc_get_rate_ctl, proc_set_rate_ctl}, + {"dis_pwt_ctl", proc_get_dis_pwt, proc_set_dis_pwt}, + {"mac_qinfo", proc_get_mac_qinfo, NULL}, + {"macid_info", proc_get_macid_info, NULL}, {"cam", proc_get_cam, proc_set_cam}, {"cam_cache", proc_get_cam_cache, NULL}, {"suspend_info", proc_get_suspend_resume_info, NULL}, {"rx_info", proc_get_rx_info, proc_reset_rx_info}, - + {"wifi_spec",proc_get_wifi_spec,NULL}, #ifdef CONFIG_LAYER2_ROAMING {"roam_flags", proc_get_roam_flags, proc_set_roam_flags}, {"roam_param", proc_get_roam_param, proc_set_roam_param}, @@ -511,12 +746,15 @@ const struct rtw_proc_hdl adapter_proc_hdls [] = { {"ampdu_enable", proc_get_ampdu_enable, proc_set_ampdu_enable}, {"rx_stbc", proc_get_rx_stbc, proc_set_rx_stbc}, {"rx_ampdu", proc_get_rx_ampdu, proc_set_rx_ampdu}, + {"rx_ampdu_factor",proc_get_rx_ampdu_factor,proc_set_rx_ampdu_factor}, + {"rx_ampdu_density",proc_get_rx_ampdu_density,proc_set_rx_ampdu_density}, + {"tx_ampdu_density",proc_get_tx_ampdu_density,proc_set_tx_ampdu_density}, #endif /* CONFIG_80211N_HT */ {"en_fwps", proc_get_en_fwps, proc_set_en_fwps}, //{"path_rssi", proc_get_two_path_rssi, NULL}, - {"rssi_disp",proc_get_rssi_disp, proc_set_rssi_disp}, +// {"rssi_disp",proc_get_rssi_disp, proc_set_rssi_disp}, #ifdef CONFIG_BT_COEXIST {"btcoex_dbg", proc_get_btcoex_dbg, proc_set_btcoex_dbg}, @@ -528,6 +766,13 @@ const struct rtw_proc_hdl adapter_proc_hdls [] = { {"sreset", proc_get_sreset, proc_set_sreset}, #endif /* DBG_CONFIG_ERROR_DETECT */ {"linked_info_dump",proc_get_linked_info_dump,proc_set_linked_info_dump}, + +#ifdef CONFIG_GPIO_API + {"get_gpio",proc_get_gpio,proc_set_gpio}, + {"set_gpio_output_value",proc_get_dummy,proc_set_gpio_output_value}, + {"config_gpio",proc_get_dummy,proc_set_config_gpio}, +#endif + #ifdef CONFIG_DBG_COUNTER {"rx_logs", proc_get_rx_logs, NULL}, {"tx_logs", proc_get_tx_logs, NULL}, @@ -538,6 +783,12 @@ const struct rtw_proc_hdl adapter_proc_hdls [] = { {"rx_ring", proc_get_rx_ring, NULL}, {"tx_ring", proc_get_tx_ring, NULL}, #endif +#ifdef CONFIG_P2P_WOWLAN + {"p2p_wowlan_info", proc_get_p2p_wowlan_info, NULL}, +#endif + {"chan_plan",proc_get_chan_plan,proc_set_chan_plan}, + {"new_bcn_max", proc_get_new_bcn_max, proc_set_new_bcn_max}, + {"sink_udpport",proc_get_udpport,proc_set_udpport}, }; const int adapter_proc_hdls_num = sizeof(adapter_proc_hdls) / sizeof(struct rtw_proc_hdl); @@ -712,6 +963,78 @@ ssize_t proc_set_odm_adaptivity(struct file *file, const char __user *buffer, si return count; } +static char *phydm_msg = NULL; +#define PHYDM_MSG_LEN 80*24 + +int proc_get_phydm_cmd(struct seq_file *m, void *v) +{ + struct net_device *netdev; + PADAPTER padapter; + PHAL_DATA_TYPE pHalData; + PDM_ODM_T phydm; + + + netdev = m->private; + padapter = (PADAPTER)rtw_netdev_priv(netdev); + pHalData = GET_HAL_DATA(padapter); + phydm = &pHalData->odmpriv; + + if (NULL == phydm_msg) { + phydm_msg = rtw_zmalloc(PHYDM_MSG_LEN); + if (NULL == phydm_msg) + return -ENOMEM; + + PhyDM_Cmd(phydm, NULL, 0, 0, phydm_msg, PHYDM_MSG_LEN); + } + + DBG_871X_SEL(m, "%s\n", phydm_msg); + + rtw_mfree(phydm_msg, PHYDM_MSG_LEN); + phydm_msg = NULL; + + return 0; +} + +ssize_t proc_set_phydm_cmd(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *netdev; + PADAPTER padapter; + PHAL_DATA_TYPE pHalData; + PDM_ODM_T phydm; + char tmp[64] = {0}; + + + netdev = (struct net_device*)data; + padapter = (PADAPTER)rtw_netdev_priv(netdev); + pHalData = GET_HAL_DATA(padapter); + phydm = &pHalData->odmpriv; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, count)) { + if (NULL == phydm_msg) { + phydm_msg = rtw_zmalloc(PHYDM_MSG_LEN); + if (NULL == phydm_msg) + return -ENOMEM; + } else { + _rtw_memset(phydm_msg, 0, PHYDM_MSG_LEN); + } + + PhyDM_Cmd(phydm, tmp, count, 1, phydm_msg, PHYDM_MSG_LEN); + + if (strlen(phydm_msg) == 0) { + rtw_mfree(phydm_msg, PHYDM_MSG_LEN); + phydm_msg = NULL; + } + } + + return count; +} + /* * rtw_odm_proc: * init/deinit when register/unregister net_device, along with rtw_adapter_proc @@ -721,6 +1044,7 @@ const struct rtw_proc_hdl odm_proc_hdls [] = { {"dbg_level", proc_get_odm_dbg_level, proc_set_odm_dbg_level}, {"ability", proc_get_odm_ability, proc_set_odm_ability}, {"adaptivity", proc_get_odm_adaptivity, proc_set_odm_adaptivity}, + {"cmd", proc_get_phydm_cmd, proc_set_phydm_cmd}, }; const int odm_proc_hdls_num = sizeof(odm_proc_hdls) / sizeof(struct rtw_proc_hdl); @@ -809,6 +1133,11 @@ void rtw_odm_proc_deinit(_adapter *adapter) remove_proc_entry("odm", adapter->dir_dev); adapter->dir_odm = NULL; + + if (phydm_msg) { + rtw_mfree(phydm_msg, PHYDM_MSG_LEN); + phydm_msg = NULL; + } } struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.h index d45a28e2bb46..9aee7bf56f68 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/rtw_proc.h @@ -40,12 +40,12 @@ void rtw_adapter_proc_replace(struct net_device *dev); #else //!CONFIG_PROC_DEBUG -struct proc_dir_entry *get_rtw_drv_proc(void) {return NULL;} -int rtw_drv_proc_init(void) {return 0;} -void rtw_drv_proc_deinit(void) {} -struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev){return NULL;} -void rtw_adapter_proc_deinit(struct net_device *dev){} -void rtw_adapter_proc_replace(struct net_device *dev){} +#define get_rtw_drv_proc() NULL +#define rtw_drv_proc_init() 0 +#define rtw_drv_proc_deinit() do {} while (0) +#define rtw_adapter_proc_init(dev) NULL +#define rtw_adapter_proc_deinit(dev) do {} while (0) +#define rtw_adapter_proc_replace(dev) do {} while (0) #endif //!CONFIG_PROC_DEBUG diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_intf.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_intf.c index 8d26548a0b24..571c4b8420bf 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_intf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_intf.c @@ -959,10 +959,7 @@ int rtw_hw_resume(_adapter *padapter) netif_device_attach(pnetdev); netif_carrier_on(pnetdev); - if(!rtw_netif_queue_stopped(pnetdev)) - rtw_netif_start_queue(pnetdev); - else - rtw_netif_wake_queue(pnetdev); + rtw_netif_wake_queue(pnetdev); pwrpriv->bkeepfwalive = _FALSE; pwrpriv->brfoffbyhw = _FALSE; @@ -1693,7 +1690,7 @@ _func_exit_; extern int console_suspend_enabled; #endif -static int rtw_drv_entry(void) +static int rtw_drv_entry(void) { int ret = 0; @@ -1754,7 +1751,8 @@ static void rtw_drv_halt(void) } #include "wifi_version.h" - +//extern int wifi_activate_usb(void); +//extern int wifi_deactivate_usb(void); extern int rockchip_wifi_power(int on); extern int rockchip_wifi_set_carddetect(int val); @@ -1765,7 +1763,6 @@ int rockchip_wifi_init_module_rtkwifi(void) printk("==== Launching Wi-Fi driver! (Powered by Rockchip) ====\n"); printk("=======================================================\n"); printk("Realtek 8723BU USB WiFi driver (Powered by Rockchip,Ver %s) init.\n", RTL8723BU_DRV_VERSION); - rockchip_wifi_power(1); return rtw_drv_entry(); } @@ -1777,18 +1774,14 @@ void rockchip_wifi_exit_module_rtkwifi(void) printk("==== Dislaunching Wi-Fi driver! (Powered by Rockchip) ====\n"); printk("=======================================================\n"); printk("Realtek 8723BU USB WiFi driver (Powered by Rockchip,Ver %s) init.\n", RTL8723BU_DRV_VERSION); - rtw_drv_halt(); rockchip_wifi_power(0); + // wifi_deactivate_usb(); } -#ifdef CONFIG_RTL8723BU + EXPORT_SYMBOL(rockchip_wifi_init_module_rtkwifi); EXPORT_SYMBOL(rockchip_wifi_exit_module_rtkwifi); -#else -module_init(rockchip_wifi_init_module_rtkwifi); -module_exit(rockchip_wifi_exit_module_rtkwifi); -#endif //module_init(rtw_drv_entry); //module_exit(rtw_drv_halt); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_ops_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_ops_linux.c index d854d7690995..b552caf212a1 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_ops_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/usb_ops_linux.c @@ -22,6 +22,16 @@ #include #include +#ifdef CONFIG_RTL8192D +#include +#endif + + +struct rtw_async_write_data { + u8 data[VENDOR_CMD_MAX_DATA_LEN]; + struct usb_ctrlrequest dr; +}; + int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) { _adapter *padapter = pintfhdl->padapter; @@ -178,13 +188,13 @@ static void _usbctrl_vendorreq_async_callback(struct urb *urb, struct pt_regs *r { if (urb) { if (urb->context) { - rtw_mfree(urb->context); + rtw_mfree(urb->context, sizeof(struct rtw_async_write_data)); } usb_free_urb(urb); } } -static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, +int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) { int rc; @@ -192,10 +202,7 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, u8 reqtype; struct usb_ctrlrequest *dr; struct urb *urb; - struct rtl819x_async_write_data { - u8 data[VENDOR_CMD_MAX_DATA_LEN]; - struct usb_ctrlrequest dr; - } *buf; + struct rtw_async_write_data *buf; if (requesttype == VENDOR_READ) { @@ -243,70 +250,7 @@ exit: return rc; } -int usb_write_async(struct usb_device *udev, u32 addr, void *pdata, u16 len) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - - int ret; - - requesttype = VENDOR_WRITE;//write_out - request = REALTEK_USB_VENQT_CMD_REQ; - index = REALTEK_USB_VENQT_CMD_IDX;//n/a - wvalue = (u16)(addr&0x0000ffff); - - ret = _usbctrl_vendorreq_async_write(udev, request, wvalue, index, pdata, len, requesttype); - - return ret; -} - -int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) -{ - u8 data; - int ret; - struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev; - struct usb_device *udev=pdvobjpriv->pusbdev; - - _func_enter_; - data = val; - ret = usb_write_async(udev, addr, &data, 1); - _func_exit_; - - return ret; -} - -int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) -{ - u16 data; - int ret; - struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev; - struct usb_device *udev=pdvobjpriv->pusbdev; - - _func_enter_; - data = val; - ret = usb_write_async(udev, addr, &data, 2); - _func_exit_; - - return ret; -} - -int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) -{ - u32 data; - int ret; - struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev; - struct usb_device *udev=pdvobjpriv->pusbdev; - - _func_enter_; - data = val; - ret = usb_write_async(udev, addr, &data, 4); - _func_exit_; - - return ret; -} #endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */ unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr) @@ -781,3 +725,436 @@ void usb_write_port_cancel(struct intf_hdl *pintfhdl) } } +void usb_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf) +{ + + precvbuf->transfer_len = 0; + + precvbuf->len = 0; + + precvbuf->ref_cnt = 0; + + if(precvbuf->pbuf) + { + precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pbuf; + precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ; + } + +} + +int recvbuf2recvframe(PADAPTER padapter, void *ptr); + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX +void usb_recv_tasklet(void *priv) +{ + struct recv_buf *precvbuf = NULL; + _adapter *padapter = (_adapter*)priv; + struct recv_priv *precvpriv = &padapter->recvpriv; + + while (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue))) + { + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) + { + DBG_8192C("recv_tasklet => bDriverStopped or bSurpriseRemoved \n"); + + break; + } + + + recvbuf2recvframe(padapter, precvbuf); + + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + +} + +void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) +{ + struct recv_buf *precvbuf = (struct recv_buf *)purb->context; + _adapter *padapter =(_adapter *)precvbuf->adapter; + struct recv_priv *precvpriv = &padapter->recvpriv; + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n")); + + ATOMIC_DEC(&(precvpriv->rx_pending_cnt)); + + if (RTW_CANNOT_RX(padapter)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved)); + DBG_8192C("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) \n", + __FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved); + goto exit; + } + + if(purb->status==0)//SUCCESS + { + if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n")); + + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + else + { + rtw_reset_continual_io_error(adapter_to_dvobj(padapter)); + + precvbuf->transfer_len = purb->actual_length; + + //rtw_enqueue_rx_transfer_buffer(precvpriv, rx_transfer_buf); + rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue); + + tasklet_schedule(&precvpriv->recv_tasklet); + } + } + else + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status)); + + DBG_8192C("###=> usb_read_port_complete => urb status(%d)\n", purb->status); + + if(rtw_inc_and_chk_continual_io_error(adapter_to_dvobj(padapter)) == _TRUE ){ + padapter->bSurpriseRemoved = _TRUE; + } + + switch(purb->status) { + case -EINVAL: + case -EPIPE: + case -ENODEV: + case -ESHUTDOWN: + //padapter->bSurpriseRemoved=_TRUE; + //RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n")); + case -ENOENT: + padapter->bDriverStopped=_TRUE; + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n")); + break; + case -EPROTO: + case -EILSEQ: + case -ETIME: + case -ECOMM: + case -EOVERFLOW: + #ifdef DBG_CONFIG_ERROR_DETECT + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL; + } + #endif + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + break; + case -EINPROGRESS: + DBG_8192C("ERROR: URB IS IN PROGRESS!/n"); + break; + default: + break; + } + + } + +exit: + +_func_exit_; +} + +u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ + int err; + unsigned int pipe; + u32 ret = _SUCCESS; + PURB purb = NULL; + struct recv_buf *precvbuf = (struct recv_buf *)rmem; + _adapter *adapter = pintfhdl->padapter; + struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); + struct recv_priv *precvpriv = &adapter->recvpriv; + struct usb_device *pusbd = pdvobj->pusbdev; + +_func_enter_; + + if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( RTW_CANNOT_RX ) || precvbuf == NULL!!!\n")); + return _FAIL; + } + + usb_init_recvbuf(adapter, precvbuf); + + if(precvbuf->pbuf) + { + ATOMIC_INC(&(precvpriv->rx_pending_cnt)); + purb = precvbuf->purb; + + //translate DMA FIFO addr to pipehandle + pipe = ffaddr2pipehdl(pdvobj, addr); + + usb_fill_bulk_urb(purb, pusbd, pipe, + precvbuf->pbuf, + MAX_RECVBUF_SZ, + usb_read_port_complete, + precvbuf);//context is precvbuf + + purb->transfer_dma = precvbuf->dma_transfer_addr; + purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + err = usb_submit_urb(purb, GFP_ATOMIC); + if((err) && (err != (-EPERM))) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status)); + DBG_8192C("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status); + ret = _FAIL; + } + + } + +_func_exit_; + + return ret; +} +#else // CONFIG_USE_USB_BUFFER_ALLOC_RX + +void usb_recv_tasklet(void *priv) +{ + _pkt *pskb; + _adapter *padapter = (_adapter*)priv; + struct recv_priv *precvpriv = &padapter->recvpriv; + struct recv_buf *precvbuf = NULL; + + while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) + { + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) + { + DBG_8192C("recv_tasklet => bDriverStopped or bSurpriseRemoved \n"); +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + if(rtw_free_skb_premem(pskb)!=0) +#endif //CONFIG_PREALLOC_RX_SKB_BUFFER + + rtw_skb_free(pskb); + break; + } + + recvbuf2recvframe(padapter, pskb); + +#ifdef CONFIG_PREALLOC_RECV_SKB + + skb_reset_tail_pointer(pskb); + + pskb->len = 0; + + skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); + +#else + rtw_skb_free(pskb); +#endif + if (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue))) { + precvbuf->pskb = NULL; + precvbuf->reuse = _FALSE; + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + } +} + + +void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) +{ + _irqL irqL; + uint isevt, *pbuf; + struct recv_buf *precvbuf = (struct recv_buf *)purb->context; + _adapter *padapter =(_adapter *)precvbuf->adapter; + struct recv_priv *precvpriv = &padapter->recvpriv; + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n")); + + ATOMIC_DEC(&(precvpriv->rx_pending_cnt)); + + if(RTW_CANNOT_RX(padapter)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved)); + + #ifdef CONFIG_PREALLOC_RECV_SKB + precvbuf->reuse = _TRUE; + #else + if(precvbuf->pskb){ + DBG_8192C("==> free skb(%p)\n",precvbuf->pskb); + rtw_skb_free(precvbuf->pskb); + } + #endif + DBG_8192C("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) \n", + __FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved); + goto exit; + } + + if(purb->status==0)//SUCCESS + { + if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n")); + precvbuf->reuse = _TRUE; + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + DBG_8192C("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__); + } + else + { + rtw_reset_continual_io_error(adapter_to_dvobj(padapter)); + + precvbuf->transfer_len = purb->actual_length; + skb_put(precvbuf->pskb, purb->actual_length); + skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb); +#ifndef CONFIG_FIX_NR_BULKIN_BUFFER + if (skb_queue_len(&precvpriv->rx_skb_queue)<=1) +#endif + tasklet_schedule(&precvpriv->recv_tasklet); + + precvbuf->pskb = NULL; + precvbuf->reuse = _FALSE; + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + } + else + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status)); + + DBG_8192C("###=> usb_read_port_complete => urb status(%d)\n", purb->status); + + if(rtw_inc_and_chk_continual_io_error(adapter_to_dvobj(padapter)) == _TRUE ){ + padapter->bSurpriseRemoved = _TRUE; + } + + switch(purb->status) { + case -EINVAL: + case -EPIPE: + case -ENODEV: + case -ESHUTDOWN: + //padapter->bSurpriseRemoved=_TRUE; + //RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n")); + case -ENOENT: + padapter->bDriverStopped=_TRUE; + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n")); + break; + case -EPROTO: + case -EILSEQ: + case -ETIME: + case -ECOMM: + case -EOVERFLOW: + #ifdef DBG_CONFIG_ERROR_DETECT + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL; + } + #endif + precvbuf->reuse = _TRUE; + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + break; + case -EINPROGRESS: + DBG_8192C("ERROR: URB IS IN PROGRESS!/n"); + break; + default: + break; + } + + } + +exit: + +_func_exit_; + +} + +u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ + _irqL irqL; + int err; + unsigned int pipe; + SIZE_PTR tmpaddr=0; + SIZE_PTR alignment=0; + u32 ret = _SUCCESS; + PURB purb = NULL; + struct recv_buf *precvbuf = (struct recv_buf *)rmem; + _adapter *adapter = pintfhdl->padapter; + struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); + struct recv_priv *precvpriv = &adapter->recvpriv; + struct usb_device *pusbd = pdvobj->pusbdev; + + +_func_enter_; + + if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( RTW_CANNOT_RX ) || precvbuf == NULL!!!\n")); + return _FAIL; + } + +#ifdef CONFIG_PREALLOC_RECV_SKB + if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) + { + if (NULL != (precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue))) + { + precvbuf->reuse = _TRUE; + } + } +#endif + + usb_init_recvbuf(adapter, precvbuf); + + //re-assign for linux based on skb + if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) + { +#ifndef CONFIG_FIX_NR_BULKIN_BUFFER + precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); +#endif + if(precvbuf->pskb == NULL) + { + if (0) + DBG_8192C("usb_read_port() enqueue precvbuf=%p \n", precvbuf); + //enqueue precvbuf and wait for free skb + rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue); + return _FAIL; + } + + tmpaddr = (SIZE_PTR)precvbuf->pskb->data; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); + skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); + + precvbuf->phead = precvbuf->pskb->head; + precvbuf->pdata = precvbuf->pskb->data; + precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); + precvbuf->pend = skb_end_pointer(precvbuf->pskb); + precvbuf->pbuf = precvbuf->pskb->data; + } + else//reuse skb + { + precvbuf->phead = precvbuf->pskb->head; + precvbuf->pdata = precvbuf->pskb->data; + precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); + precvbuf->pend = skb_end_pointer(precvbuf->pskb); + precvbuf->pbuf = precvbuf->pskb->data; + + precvbuf->reuse = _FALSE; + } + + ATOMIC_INC(&(precvpriv->rx_pending_cnt)); + + purb = precvbuf->purb; + + //translate DMA FIFO addr to pipehandle + pipe = ffaddr2pipehdl(pdvobj, addr); + + usb_fill_bulk_urb(purb, pusbd, pipe, + precvbuf->pbuf, + MAX_RECVBUF_SZ, + usb_read_port_complete, + precvbuf);//context is precvbuf + + err = usb_submit_urb(purb, GFP_ATOMIC); + if((err) && (err != (-EPERM))) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status)); + DBG_8192C("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status); + ret = _FAIL; + } + +_func_exit_; + + return ret; +} +#endif // CONFIG_USE_USB_BUFFER_ALLOC_RX + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_regd.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_regd.c index 54d1331ba81e..04ffe781a410 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_regd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_regd.c @@ -268,10 +268,15 @@ static void _rtw_reg_apply_radar_flags(struct wiphy *wiphy) if (!_rtw_is_radar_freq(ch->center_freq)) continue; #ifdef CONFIG_DFS - if (!(ch->flags & IEEE80211_CHAN_DISABLED)) - ch->flags |= IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_NO_IBSS; -#endif + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) { + ch->flags |= IEEE80211_CHAN_RADAR; + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) + ch->flags |= (IEEE80211_CHAN_NO_IBSS|IEEE80211_CHAN_PASSIVE_SCAN); + #else + ch->flags |= IEEE80211_CHAN_NO_IR; + #endif + } +#endif //CONFIG_DFS #if 0 /* @@ -354,16 +359,19 @@ static void _rtw_reg_apply_flags(struct wiphy *wiphy) rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + ch = ieee80211_get_channel(wiphy, freq); if (ch) { - if (channel_set[i].ScanType == SCAN_PASSIVE) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) - ch->flags = IEEE80211_CHAN_PASSIVE_SCAN; -#else // kernel >= 3.14 + if (channel_set[i].ScanType == SCAN_PASSIVE) { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) + ch->flags = (IEEE80211_CHAN_NO_IBSS|IEEE80211_CHAN_PASSIVE_SCAN); + #else ch->flags = IEEE80211_CHAN_NO_IR; -#endif // kernel >= 3.14 - else + #endif + } + else { ch->flags = 0; + } } } @@ -478,26 +486,52 @@ static const struct ieee80211_regdomain *_rtw_regdomain_select(struct #endif } -static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, - struct wiphy *wiphy, - void (*reg_notifier) (struct wiphy * wiphy, - struct regulatory_request * - request)) +void _rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct rtw_regulatory *reg = NULL; + + DBG_8192C("%s\n", __func__); + + _rtw_reg_notifier_apply(wiphy, request, reg); +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) +int rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +#else +void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +#endif +{ + _rtw_reg_notifier(wiphy, request); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) + return 0; + #endif +} + +void rtw_reg_notify_by_driver(_adapter *adapter) +{ + if ((adapter->rtw_wdev != NULL) && (adapter->rtw_wdev->wiphy)) { + struct regulatory_request request; + request.initiator = NL80211_REGDOM_SET_BY_DRIVER; + rtw_reg_notifier(adapter->rtw_wdev->wiphy, &request); + } +} + +static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy) { const struct ieee80211_regdomain *regd; - wiphy->reg_notifier = reg_notifier; + wiphy->reg_notifier = rtw_reg_notifier; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; -#else // kernel >= 3.14 + #else wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; -#endif // kernel >= 3.14 - + #endif + regd = _rtw_regdomain_select(reg); wiphy_apply_custom_regulatory(wiphy, regd); @@ -518,11 +552,8 @@ static struct country_code_to_enum_rd *_rtw_regd_find_country(u16 countrycode) return NULL; } -int rtw_regd_init(_adapter * padapter, - void (*reg_notifier) (struct wiphy * wiphy, - struct regulatory_request * request)) +int rtw_regd_init(_adapter * padapter) { - //struct registry_priv *registrypriv = &padapter->registrypriv; struct wiphy *wiphy = padapter->rtw_wdev->wiphy; #if 0 @@ -540,17 +571,9 @@ int rtw_regd_init(_adapter * padapter, __func__, rtw_regd->alpha2[0], rtw_regd->alpha2[1]); #endif - _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier); + _rtw_regd_init_wiphy(NULL, wiphy); return 0; } - -void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) -{ - struct rtw_regulatory *reg = NULL; - - DBG_8192C("%s\n", __func__); - - _rtw_reg_notifier_apply(wiphy, request, reg); -} #endif //CONFIG_IOCTL_CFG80211 + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_version.h b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_version.h index 29eb9dd91bea..7cd319cd6e01 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_version.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/wifi_version.h @@ -1,13 +1,13 @@ /* * Yongle Lai @ Rockchip */ -#ifndef WIFI_VERSION_H -#define WIFI_VERSION_H +#ifndef _WIFI_VERSION_H_ +#define _WIFI_VERSION_H_ /* - * Marvell MV8686 driver version. + * Broadcom BCM4319 driver version. */ -#define RTL8723BU_DRV_VERSION "3.00.WFD" +#define RTL8723BU_DRV_VERSION "4.39.WFD" #endif /* WIFI_VERSION_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/xmit_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/xmit_linux.c index 43af7562010a..db9b311f321f 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/xmit_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/linux/xmit_linux.c @@ -21,6 +21,7 @@ #include +#define DBG_DUMP_OS_QUEUE_CTL 0 uint rtw_remainder_len(struct pkt_file *pfile) { @@ -187,28 +188,78 @@ void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 } } +void dump_os_queue(void *sel, _adapter *padapter) +{ + struct net_device *ndev = padapter->pnetdev; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + int i; + + for (i=0;i<4;i++) { + DBG_871X_SEL_NL(sel, "os_queue[%d]:%s\n" + , i, __netif_subqueue_stopped(ndev, i)?"stopped":"waked"); + } +#else + DBG_871X_SEL_NL(sel, "os_queue:%s\n" + , netif_queue_stopped(ndev)?"stopped":"waked"); +#endif +} + #define WMM_XMIT_THRESHOLD (NR_XMITFRAME*2/5) -void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt) +inline static bool rtw_os_need_wake_queue(_adapter *padapter, u16 qidx) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) - u16 queue; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - queue = skb_get_queue_mapping(pkt); if (padapter->registrypriv.wifi_spec) { - if(__netif_subqueue_stopped(padapter->pnetdev, queue) && - (pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD)) - { - netif_wake_subqueue(padapter->pnetdev, queue); - } + if (pxmitpriv->hwxmits[qidx].accnt < WMM_XMIT_THRESHOLD) + return _TRUE; + } else { + return _TRUE; + } + return _FALSE; +#else + return _TRUE; +#endif +} + +inline static bool rtw_os_need_stop_queue(_adapter *padapter, u16 qidx) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + if (padapter->registrypriv.wifi_spec) { + /* No free space for Tx, tx_worker is too slow */ + if (pxmitpriv->hwxmits[qidx].accnt > WMM_XMIT_THRESHOLD) + return _TRUE; } else { - if(__netif_subqueue_stopped(padapter->pnetdev, queue)) - netif_wake_subqueue(padapter->pnetdev, queue); + if(pxmitpriv->free_xmitframe_cnt<=4) + return _TRUE; } #else - if (netif_queue_stopped(padapter->pnetdev)) + if(pxmitpriv->free_xmitframe_cnt<=4) + return _TRUE; +#endif + return _FALSE; +} + +void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + u16 qidx; + + qidx = skb_get_queue_mapping(pkt); + if (rtw_os_need_wake_queue(padapter, qidx)) { + if (DBG_DUMP_OS_QUEUE_CTL) + DBG_871X(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx); + netif_wake_subqueue(padapter->pnetdev, qidx); + } +#else + if (rtw_os_need_wake_queue(padapter, 0)) { + if (DBG_DUMP_OS_QUEUE_CTL) + DBG_871X(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(padapter)); netif_wake_queue(padapter->pnetdev); + } #endif rtw_skb_free(pkt); @@ -259,30 +310,53 @@ void rtw_os_xmit_schedule(_adapter *padapter) #endif } -static void rtw_check_xmit_resource(_adapter *padapter, _pkt *pkt) +static bool rtw_check_xmit_resource(_adapter *padapter, _pkt *pkt) { + bool busy = _FALSE; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) - u16 queue; + u16 qidx; + + qidx = skb_get_queue_mapping(pkt); + if (rtw_os_need_stop_queue(padapter, qidx)) { + if (DBG_DUMP_OS_QUEUE_CTL) + DBG_871X(FUNC_ADPT_FMT": netif_stop_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx); + netif_stop_subqueue(padapter->pnetdev, qidx); + busy = _TRUE; + } +#else + if (rtw_os_need_stop_queue(padapter, 0)) { + if (DBG_DUMP_OS_QUEUE_CTL) + DBG_871X(FUNC_ADPT_FMT": netif_stop_queue\n", FUNC_ADPT_ARG(padapter)); + rtw_netif_stop_queue(padapter->pnetdev); + busy = _TRUE; + } +#endif + return busy; +} - queue = skb_get_queue_mapping(pkt); - if (padapter->registrypriv.wifi_spec) { - /* No free space for Tx, tx_worker is too slow */ - if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD) { - //DBG_871X("%s(): stop netif_subqueue[%d]\n", __FUNCTION__, queue); - netif_stop_subqueue(padapter->pnetdev, queue); - } - } else { - if(pxmitpriv->free_xmitframe_cnt<=4) { - if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue))) - netif_stop_subqueue(padapter->pnetdev, queue); +void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + int i; + + for (i=0;i<4;i++) { + if (qcnt_freed[i] == 0) + continue; + + if(rtw_os_need_wake_queue(padapter, i)) { + if (DBG_DUMP_OS_QUEUE_CTL) + DBG_871X(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), i); + netif_wake_subqueue(padapter->pnetdev, i); } } #else - if(pxmitpriv->free_xmitframe_cnt<=4) - { - if (!rtw_netif_queue_stopped(padapter->pnetdev)) - rtw_netif_stop_queue(padapter->pnetdev); + if (qcnt_freed[0] || qcnt_freed[1] || qcnt_freed[2] || qcnt_freed[3]) { + if(rtw_os_need_wake_queue(padapter, 0)) { + if (DBG_DUMP_OS_QUEUE_CTL) + DBG_871X(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(padapter)); + netif_wake_queue(padapter->pnetdev); + } } #endif } @@ -441,7 +515,7 @@ _func_enter_; drop_packet: pxmitpriv->tx_drop++; - rtw_skb_free(pkt); + rtw_os_pkt_complete(padapter, pkt); RT_TRACE(_module_xmit_osdep_c_, _drv_notice_, ("rtw_xmit_entry: drop, tx_drop=%d\n", (u32)pxmitpriv->tx_drop)); exit: diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/osdep_service.c b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/osdep_service.c index 681889bf964f..dcef0e75acf5 100755 --- a/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/osdep_service.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723bu/os_dep/osdep_service.c @@ -751,7 +751,7 @@ inline void *dbg_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_a void *p; if(match_mstat_sniff_rules(flags, size)) - DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size); + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%zu)\n", func, line, __FUNCTION__, size); p = _rtw_usb_buffer_alloc(dev, size, dma); @@ -768,7 +768,7 @@ inline void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *a { if(match_mstat_sniff_rules(flags, size)) - DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size); + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%zu)\n", func, line, __FUNCTION__, size); _rtw_usb_buffer_free(dev, size, addr, dma); @@ -782,7 +782,7 @@ inline void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *a #endif /* defined(DBG_MEM_ALLOC) */ -void* rtw_malloc2d(int h, int w, int size) +void* rtw_malloc2d(int h, int w, size_t size) { int j; @@ -1404,7 +1404,12 @@ void rtw_msleep_os(int ms) { #ifdef PLATFORM_LINUX - + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) + if (ms < 20) { + unsigned long us = ms * 1000UL; + usleep_range(us, us + 1000UL); + } else + #endif msleep((unsigned int)ms); #endif @@ -1423,16 +1428,19 @@ void rtw_msleep_os(int ms) } void rtw_usleep_os(int us) { - #ifdef PLATFORM_LINUX - - // msleep((unsigned int)us); - if ( 1 < (us/1000) ) - msleep(1); + + // msleep((unsigned int)us); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) + usleep_range(us, us + 1); + #else + if ( 1 < (us/1000) ) + msleep(1); else msleep( (us/1000) + 1); + #endif +#endif -#endif #ifdef PLATFORM_FREEBSD //Delay for delay microseconds DELAY(us);